composite design pattern for Codea

This is a follow up of http://codea.io/talk/discussion/6446/draggable-objects-and-design-patterns.

Trying to use Simeon component template, i found out that it was not meant to manage a hierachy of objects (objects made of components, themselves made of components, etc…). To make complex objects out of simple assemblies of simple objects, is really what i am looking for. Reading the provided links, i found out that what i wanted is really the composite design pattern.

So i tried to implement one, and i found out that:

  • draw() and touched() are quite easy to propagate.
  • update() is a real headache, because i want 2 way communication between parent and children, and propagation of the connunications through the whole tree, and coherent results.

I also came to the conclusion that if i want a 2 way communication, the Composite class will be more complex to understand and use. So i decided to split my goal in 3 targets, from the simplest (and weakest) to the most complex (but hopefully more useful):

  • Composite0: is a composite class that manage only top-down information flow. It is close to Simeon Component, with the addition that the top-bottom communication process is taken in charge via the definition of an interface table.

  • Composite1: is like Composite1, except 1 feedback variable is passed around, down and up, and used to block the update of all the tree is one component refuses the consequence of the update. This is the minimal tbottom-up control flow to do something useful.

  • Composite2: is a composite class that manage top-down and bottom-up information flow, via 2 interfaces, and control the flow via a meta variable. Component order is made unimportant. Conflicts between components are managed with an update rule (that can be customized for each variable passed up). Infinite loops are managed. The price to pay is more complexity of use (in the sub classes : 2 interfaces to define, a bit of meta communication (refuseUpdate, sendMessage), and you have to avoid creating pitfalls), more memory and cpu used for updating. It seems to work well though, i have to use it to relky make something to verify it really helps to build complex reusable objects out of simpler ones.

I’ve made a toy project (a series of boxes in hierarchy) and implented it with the 3 Composite class, to verify my code works as advertized. I will post the 3 projects below, and hope some of you are interested and provide me some feedback.

#Composite0

full project: https://gist.github.com/anonymous/97a330f75a95dc632a33.

#Composite1.
.
project: https://gist.github.com/anonymous/f5b396dc34f312a27b1a.

#Composite2:

project: https://gist.github.com/anonymous/6eb08e227fd9b74356f9
note: the tab ‘item’ was left there by mistake, it is not used (item2 is used)

thanks for reading!

Thanks for posting all of these. Composite design is also something I’ve been thinking about a lot recently. If I can clean the code up, I’ll post my composite experiment. I find though that in actual projects (if that makes sense, rather than exercises or experiments), I rarely end up using the “libraries” that I or someone else has made and usually end up doing something very simple, like having each entity own an instance of the various components, as in

self.mesh=Mesh(properties) --owns an instance of the Mesh class

Are the different patterns you’ve described here meant to be used alongside each other in one project, or are you thinking you’ll choose one depending on the project?

I think of using composite2 only, for my buttons/widgets. The other versions are not powerful enough. I made them as intermediate steps, since composite2 was really difficult to set up.
[edit] my next step will be to make a wrapper to transform a ‘regular’ class (as we are use to write with codea) into a composite class that

  • has same functionnalities,
  • but can be used as a composite object by another composite object,
  • with minimum overhead work for the programmer.

I had a play around with the composite2 demo, it’s very impressive (though the composite code seems quite complex.)

Just to expand a bit on my comment above, about having an entity own instances of various components, one technique I use is have the init function of the component class expose a method in its parent object, eg the physics component init contains:

self.p.move = function(velx, vely) self:move(velx, vely) end --expose interface for setting absolute velocity

Where self.p is the parent entity. Then other components, AI or whatever, can access the interface via the parent, eg self.p:move(velx, vely)

interesting, thanks for the tip. Need to think about it.
And thanks for trying Composite2 also! I understand the code looks quite complex, but it is the simplest version (for now) that achieves my goals. My Next challenge: turn it into a wrapper so i can not even think about it any more, just use it seamlessly. This is what happened for me with the Event() class i was granted last year, which is so handy and simple once you trust it, that i couldnt do without it any more! So maybe this is possible with this pattern too. Maybe…