krstffr / stupid-space-game

A stupid space game.
0 stars 0 forks source link

Mixins: pass down update to inheriting objects #9

Open krstffr opened 11 years ago

krstffr commented 11 years ago

@klase see how I did it for the moveRockets method. The problem which might/will arise is when multiple mixins pass down multiple inherited updates (I think!). Now I created a fake mixin which does nothing but console.log something just to try if the SpaceShip class inherted both mixins update-methods.

Also I'm getting a bit drunk on folköl so this might make no sense. Going out now!

Also I wrote a longer issue on mixins (where to put them etc. do you think a mixins folder makes sense??) etc. but it disappeared.

krstffr commented 11 years ago

@klase

http://ringjs.neoname.eu/

Multiple class inheritance etc. and methods can be altered in a way which seems to be what we need for the update() method etc. Maybe?

klase commented 11 years ago

Or http://ejohn.org/blog/simple-javascript-inheritance/

krstffr commented 11 years ago

Ah nice!

I guess as long as we got this: this._super(); we're good?

klase commented 11 years ago

yep!

krstffr commented 11 years ago

What (I think) is better about ring.js is the multiple inheritance-stuff. Take these three classes which and enemy class might want to inherit:

---------------------- . -------------- . ---------------
| shootingStuffClass | . | moverClass | . | shieldClass |
---------------------- . -------------- . ---------------

As they are unrelated to each other there's not a linear inheritance-chain (is that a word?) which is required in the other simple-javascript-inheritance-example? At least I think that's the case?

Compare the Ninja class in the simple-example compared to the Spiderman class in the ring.js-example. The Spiderman class inherits from two unrelated classes and I don't think that's possible in the simple-case?

A very poor diagram
simple: Person -> Ninja
ring.js: Human + Spider -> Spiderman
krstffr commented 11 years ago

I made a test with ring.sj (branch: ring-js-test).

The multiple inheritance works (SpaceShip inherits TestMixin and Shooter and boths update() methods are ran by SpaceShip). Code SUPERMESSY though as I mainly made it to try if it worked at all as I wanted it to.

klase commented 11 years ago

Yep you're right about the difference between simple vs ring.js. Can't help but feel it would be nice to try and work with the prototypal nature of javascript rather than try to force a class based style through third party libraries to get a better understanding of the language itself. Probably need to do some more reading though cause I still feel a bit lost when it comes to prototypal inheritance..

krstffr commented 11 years ago

Alright, sounds like a challange/fun!

Let's do more reading and let each other know what we find out!

krstffr commented 11 years ago

Hmm, I'm not really sure what to look for. I'm thinking "I need multiple inheritance support" and google it and sometimes find promising ways of achieving it, but then again maybe I'm asking the wrong question in the first place?

Is the fact that we need multiple inheritance support true or not? Or do we even know that (yet)?

My brain hurts. :)

Anyway: IF we need it, I played around some with it here: https://github.com/krstffr/js-inheritance-testing in three different ways/branches (two with external libs (one of them fails (master), one which passes but is not very DRY (mixins)) and one with ring.js (ring-js) which is of course an external class system).

Though as I said I'm not sure I'm trying to accomplish the right things here. :)

Oh well!

klase commented 11 years ago

Haha I don't think we know yet. Maybe we could use something like this:

function MyClass(name) { this.name = name; }

MyClass.prototype.doStuff = function() { // generic behaviour }

var myObj = new MyClass('foo');

var myObjSpecial = new MyClass('bar'); myObjSpecial.doStuff = function() { // do specialised stuff //call the generic implementation: MyClass.prototype.doStuff.call(this /, args.../); }

krstffr commented 11 years ago

Yes, that's pretty simliar to what I did in the mixins-branch of my test-thing. What's hard I think is the multiple inheritance. It works in the mixins branch (and the ring.js of course), but the mixins branch doesn't inherit parents methods if you don't specify all parents explicitly.

I have these objects: Mammal, Human(is a Mammal), SoccerPlayer(is a Human), Wizard (is a Human) and Messi (is a SoccerPlayer and a Wizard). (Yes: the Messi-thing is super tacky.) I of course want a Soccer Player to also be a human and a mamal and inherit all their stuff etc. This works all works well with ring.js, but in the mixins branch I have to do this to inherit all of that good stuff to Messi (after I've declared him):

Mammal.call(Messi.prototype);
Human.call(Messi.prototype);
SoccerPlayer.call(Messi.prototype);
Wizard.call(Messi.prototype);

Using ring.js I only add his direct "parents" when declaring the Messi-object: Messi = ring.create([SoccerPlayer, Wizard], { /* Messis own stuff */ }) and he inherits all the mammal and human (and whichever parents) stuff as well.

If using the anti-DRY-mixins-way I also have to remember to add any new parent objects which I might add later (for example between Human and Mammal) to all sub objects, while ring.js will take care of that for me. But it is of couse an external library. :) (Though not a game specific one!)

klase commented 11 years ago

What if we take this approach: http://stackoverflow.com/questions/16020577/proper-prototypal-inheritance

In the above case if we were to create another 'class' based on Mage we would still have access to the base class methods as it would just go up the prototype chain until it finds the function? It might be a bit more convoluted but feels like it's using javscript in a more 'native' way

krstffr commented 11 years ago

Yep, the thing that (I think) is missing from that approach is: what if the Mage is also a Lizard, and wants to inherit some base stuff from Lizard? You can't put the Lizard in the chain (as it's not a "child" or "parent" of Player), and you can't inherit multiple objects to the Mage in that way (as far as I'm concerned).

We can do that if we go the the mixin way which I would still consider native as there're no third party stuff going on, but then we will have to specify each parent object literally. Maybe it could be a good thing though, as you'd have total control over each objects inheritance's (even if it means you have to repeat some stuff from object to object)?

krstffr commented 11 years ago

Ps. började läsa den här en gång. Tror jag ska ge den ett nytt försök! Verkar vara rätt så gedigen: http://chimera.labs.oreilly.com/books/1234000000262/index.html