Da Gampa's Code

Personal weblog of Jakub Hampl.

Ask me whatever you want. I'll reply to whatever I want.

Coupling

Today I was debugging some code. I spent the whole day on it, I ended up writing only 2 lines of code to fix the problem. Where did I spend all of my time? Trying to understand what the code did and how information actually travelled through the system. I’d like to discuss a few ways software systems communicate information and the impact of those choices on the maintainability of that software.

Criteria

We can abstract away and say that each method of communication introduces some degree of coupling - that is how much the two software components depend on each other.

Coupling has a few advantages and disadvantages. Loose coupling allows components to be more easily taken apart and reused with other components, decreasing the amount and complexity of doing that. Tight coupling on the other hand tends to be logically simpler.

Method calls

The simplest method is for one object to call methods on another object. This usually adds incredibly tight coupling making rewriting of both components necessary. Sometimes this also induces circular dependency issues, when object A needs to call methods of object B who needs to call methods on object A.

The principal method of reducing coupling is a variant of Duck Typing: where component A doesn’t need to know or care anything about the exact type or implementation details of object B as long as object B can understand some methods that object A requires.

There are many variations of this idea e.g.: contracts, interfaces or protocols.

Method calls, unlike all of the remaining techniques holds a unique advantage: when reading the code, you can easily work out the flow within your program (there are still asynchronous issues, but at least it is clear which code will handle the future). All you need to know is the type of the variable and the method name, and then you can usually easily see the code responsible. Furthermore support in debugging tools is usually excellent.

Events; Callbacks

This technique works by having object A have a method that allows object B to subscribe its method to be called by object A whenever it decides to do so. In pseudocode:

window = new Window # window has a method called display
button  = new Button("Click to see a window")
button.onClick(window.display)
# when the user clicks the button, the method window.display will be called

Events can have various implementations that are better or worse. You can have very direct event distribution methods like the pseudocode above, or you can have quite indirect ones, like a global Notification Center object that all other components subscribe to or even a remote web service communicating with different components. The direct method we can see above is almost as good as method calls as we can see which object is talking to which object, the only thing that becomes more complicated is when does the call occur.

However when there is some central delivery mechanism (or perhaps code relies on bubbling mechanisms or similar), it becomes increasingly difficult to figure out what code is going to handle it. If you see code like:

NotificationCenter.broadcast(myEventNameVariable, eventPayload)

It takes quite a while to find the relevant code that responds to that. What is also implicit in these systems is that where using methods you would have code like this:

 class A
   method doSomethingWithMethods()
      b.foo()
      c.bar()
      d.bum()

class B
   method foo()
     doFoo()

class C
   method bar()
     doBar()

class D
   method bum()
     doBum()

With events you can rewrite that as:

 class A
   method doSomethingWithEvents()
      NotificationCenter.broadcast('somethingDone')

class B
   NotificationCenter.on('somethingDone', doFoo())

class C
   NotificationCenter.on('somethingDone', doBar())

class D
    NotificationCenter.on('somethingDone', doBum())

As you can see, with the first code we can clearly see that calling A.doSomethingWithMethods will first execute A.doFoo then B.doBar and finally C.doBum, with events we, by looking at A.doSomethingWithEvents we have no idea what is going to happen. We have to do a global search through our codebase to find all the places that the event string occurs. We have no guarantee in which order will the methods be executed. Furthermore, when in the first case we get an error on line 3 of method A, we know that object B is likely innocent, the likely culprit is object C. In the second case we will be lucky if we can trace it to object A at all, let alone have an idea to which of the listeners belongs the blame.

When should one use such a system then? In highly decoupled systems or as an alternative to local events. As such bubbling is often a good solution, as a component for which tighter coupling is appropriate can subscribe directly to the object, whereas a loose component can subscribe at the top-level. (e.g. I want to make a backup whenever the user saves something, but I have a fully generic backup solution, therefore I could subscribe to a top-level backup event as I don’t care if the file being saved is a text document or a video file.)

Value observing; binding

Some languages support adding observers to variables - whenever a variable on a object changes, some object can run some code in response. If this is doubled, then it is called binding, where changing one variable automatically changes the value of another.

This looks like a really nice idea and typically allows for impressive demos where very little code can achieve a lot. But when you have a large and complex system, you start to believe that value-observing is a terrible idea - especially between objects. In most mutable languages we are used to assigning to variables all the time and it is generally considered fairly safe (except for loosing the previous value). Often we spend significant time debugging code until we realize that actually assigning to a variable triggered some code that triggered an asynchronous request that causes a logic error. Perhaps this technique could be more tolerable if the variable had to explicitly declare itself observable before this started working.

My recommendation: don’t use value-observing other then inside the same object, and prefer easier to understand method such as setters and getters.

Conclusion

Consider the ease of debugging later when writing your code. Don’t just add observers all over the place because it looks easier than defining a bunch of methods. Just because you made a brand-new notification service doesn’t mean you need to use it for two halves of the same component. That’s like two people in the same room sending each other text messages: possible, but awkward.

#tech 

Check out my sister’s new site, where she features some of her work; a sample of which you see above.

Check out my sister’s new site, where she features some of her work; a sample of which you see above.

#sister #art 

thaliazeniou asked:
What do you want?

I have only one desire
to be holy
  Set apart for you, Master.

As I perceive a faint wisp
of your glory
  I grovel in the dust.

I long for you to touch me
to crush my head
  As a man crushes a beetle.

But how can the Holy mingle
with the loathsome?
  And yet I demand no less.

#poem #repentance #love #God 

An Academic Poem

"The florist loved Mary" 1 “and”2 “Mary loved the florist.” 1
“Pinning them down as
attracted or unattracted,
interested or uninterested,
they enter into a new kind of arena, of all-or-nothing commitments.” 3
“An almost comically tricky object for understanding and analysis.” 3
“It does indeed start this snowball of epistemic virtue!” 3

"The florist loved Mary." 1
“Mary was the agent and the florist the patient.” 1
“Love worries that I implicitly cleave to a classical view,” 3
“that Mary is” 1 “the one I want to pursue” 9
“The symbol loosens the bond between agent and world” 9
“It is pretty clear that it is simply a bluff”. 4
“Love sure knows how to hurt a guy!” 3

"Communication works best
among those who not only share a language
but who share a lot” 5 “more”2.
“Communication involves an exchange of signals with a particular physical shape.
They influence by impacting sensory surfaces.” 6
“But they also play an irreducible role as the material symbols they are.” 9
“It does indeed start this snowball of epistemic virtue!” 3

"I am both following and steering your own cognitive activities,
as you are both following and steering mine.” 7
“Now for a confession:” 9
“A very abstract relationship, not a substantial or physical one” 6 “we have” 2
“I experience the feeling of sadness” 8 “as essentially transformative” 9
“I come to understand what it was like for you.” 8
“Love sure knows how to hurt a guy!” 3


References

Apart from their aesthetic value, they are fine readings in Philosophy of Mind.

  1. Bechtel (1994).
  2. O’Reagan & Noë (2001).
  3. Clark (2004).
  4. Stitch (1978).
  5. Cummins (1996).
  6. O’Brien & Opie (2002).
  7. Churchland (2002) as cited in O’Brien & Opie (2002).
  8. Davies & Stone (2001).
  9. Clark (2006).

#academia #love #poem #joke 

Writing your own Canvas Scene Graph

Writing a scene-what? The HTML5 Canvas api provides primitive methods to express shapes, strokes and fills, which is all fine and dandy, but in a lot of situations we tend to think of drawing as composed of objects. E.g. to draw what I see from my window I need to draw a tree, a house and some grass, not a sequence of paths.

This is true even more when we start animating, typically objects that are part of another object move when the parent object moves.

One way to abstract this is to have a graph of objects where some objects are contained in other objects and each object takes care of drawing itself. This is called scene graph rendering.

In this article I will show how to build your very own scene graph renderer for the HTML5 canvas. If you are simply looking for a full-featured, pre-built solution, I recommend checking out CAAT. But sometimes you need something easily customizable/lightweight. We will build a single CoffeeScript class that implements everything necessary.

The basics

The first thing that any computer graphics program has to deal with are coordinate systems. We want each object to have it’s own independent coordinate system and itself be defined in terms of it’s parents. In general this indepence is one of the best reasons for using a scene-graph solution, since canvas tends to have a lot of global state, and you might often face the situation that changing one part of your composition affects a very different part. We wish to avoid that.

The simplest way to solve this is to have each object be it’s own canvas. So let’s start coding:

class Entity
  width: 0
  height: 0

  constructor: (@width, @height) ->
    # Create the canvas we will be rendering the object to
    @canvas = document.createElement('canvas')
    @canvas.width = @width
    @canvas.height = @height

  # Call this function to render out the object, returns a Canvas instance
  render: ->
    ctx = @canvas.getContext('2d')
    # Clear the canvas, important for animation
    ctx.clearRect(0, 0, @width, @height)
    @draw(ctx)
    @canvas # return the canvas

  # This function should be overriden in subclasses  
  draw: (ctx) ->

Now each subclass has to only implement the draw method with it’s own set of drawing primitives.

Composition

We hover are still not a graph, there is no way in which objects can have no children. First we need to add a few more properties to our class:

x: 0
y: 0
children: []
parent: null

x and y are numbers that determine where will the object be drawn in the parent's coordinate system. Let's implement a default draw method, that will render the children:

draw: (ctx) ->
  for child in @children
    ctx.drawImage(child.render(), child.x, child.y)
  false # return some value, otherwise CoffeeScript will return an array

The drawImage method takes an Image, Canvas or Video object and draws it at specified coordinates. Since render returns a canvas instance with the object drawn in it, we can now render it in the parent canvas. A simple demo of this class:

Rotations

To make this even more worth it, we would like to support rotating any object and having all it’s children be rotated as well. Again we need to add a rotation attribute:

rotation: 0

and tweak our draw function:

draw: (ctx) ->
  for child in @children
    if child.rotation isnt 0
      ctx.save()
      ctx.translate(child.x, child.y)
      ctx.rotate(child.rotation)
      ctx.drawImage(child.render(), 0, 0)
      ctx.restore()
    else
      ctx.drawImage(child.render(), child.x, child.y)
  false

Canvas provides us with all the magic we need. We save the current context, then shift our origin point to the child’s coordinates (NB: we are going to be rotating children around their origin point, perhaps you would like to implement rotation around center point). Then we do the rotation and drawing and then we simply restore our context to it’s original point of origin.

Shaping up the API

First of all since most entity objects will want to override draw in one way or another we might simply use a Kestrel in the constructor and allow the user to optionally provide it when initiating the class:

constructor: (@width, @height, @draw = @draw) ->
    @canvas = document.createElement('canvas')
    @canvas.width = @width
    @canvas.height = @height

The @draw = @draw might look a bit awkward at first glance, but it assigns as a default our own implementation of draw if the user hasn’t provided one. The js looks like this:

function(draw) {
  this.draw = (draw != null ? draw : this.draw);
}

Next let’s have a single function for instantiating new Entities and simultaneously adding them as children:

add_child: (width, height, draw) ->
  child = new Entity width, height, draw
  @children.push child
  child.parent = @
  child # return `child` so that we can do stuff like `collection = scene.add_child 30, 30`

You might want to create another class that wraps up some common functionality as creating the top level Entity (typically called Scene) and setting its canvas as the one actually displayed in the document and setting up animation loops and so on. I’ll leave that as an exercise for the reader (hint: look at the fiddles, there you have the basics).

Caching

If you draw expensive things in your objects (and some things in canvas are pretty expensive like shapes with multiple gradients/shadows), you might not want to redraw them 60 times per second. Our architecture allows us to prevent that rather easily.

Again we add two more attributes:

# This is what the user sets
perform_caching: no
# This tracks whether or not we should render
is_cached: no

Now let’s modify our render function:

render: ->
  return @canvas if @perform_caching and @is_cached
  ctx = @canvas.getContext('2d')
  ctx.clearRect(0,0,@width, @height)
  @draw(ctx)
  @is_cached = true
  @canvas

We skip all the work when caching is enabled, since the canvas still contains all that was drawn into it.

Wrapping up

And that’s basically all there is to it. There are a myriad of features you can add like more transformations apart from rotations, primitive entity subclasses (think something like Sprite entity), etc. The complete class is here:

#canvas #coffee-script #html5 

What bothers me about ACTA, SOPA, etc.

There is a significant problem with these laws (acts, agreements, whatever) even if you don’t care about IP legislation at all.

The current entertainment industry arose under a certain set of conditions. These condition have changed and the industry is failing to keep pace1. So instead of transforming into something modern they attempt to change the conditions back to their outdated state via the law.

Let me make an analogy: imagine that Catholic priests started lobbying for the state to ban atheism because they were losing their jobs. The current legislation is the same thing for the entertainment industry.

Many people view the current protests as some sort of hippie free-lunch2 absurdity. What is in fact at stake is however a core value of capitalism: if you can’t make a profit with your product, you don’t make the government protect your market, you make your product better or you shrivel up and die.


  1. Actually it’s not even doing so bad, but that’s a separate issue.

  2. The Pirate culture tends to elicit such views with slogans such as “Sharing is caring” .

#politics #intellectual property 

I don’t believe that 2012 will be the end of the world, but it’s a fun topic.

So: Good luck with surviving the apocalypse and any other similarly worthwhile endeavors in which you may partake! Happy 2012!

I don’t believe that 2012 will be the end of the world, but it’s a fun topic.

So: Good luck with surviving the apocalypse and any other similarly worthwhile endeavors in which you may partake! Happy 2012!

#pf #end of world 

Krtek

Zdeněk Miler
1921-2011

#death #art #krtek