## middleclass & extras: middleclass 3.0 is out!

Luiji
Party member
Posts: 396
Joined: Mon May 17, 2010 6:59 pm

### Re: MiddleClass & MindState: Object Orientation for LUA

This is the most awesome thing that has ever been created in the history of forever for LOVE.

Man, this makes things so much easier! In my game I was implementing my own minimal class system per-class (basically writing the :new function multiple times). The sub-classing, packages, and everything have made my game development so much faster!

I was going to try out PASSION, but it is listed as pre-alpha quality on the forum, so I'm currently avoiding it, but when it is finished I'll try to integrate it into my game!
Good bye.

Luiji
Party member
Posts: 396
Joined: Mon May 17, 2010 6:59 pm

### Re: MiddleClass & MindState: Object Orientation for LUA

Have you considered adding Interfaces as a capability?

For those who don't know what those are: Interfaces are objects that define what classes inheriting it must implement. Think of it as a class that prints errors if not all of it's functions are reimplemented.
Good bye.

kikito
Inner party member
Posts: 3153
Joined: Sat Oct 03, 2009 5:22 pm
Contact:

### Re: MiddleClass & MindState: Object Orientation for LUA

Hi there!

I'm glad you liked MiddleClass & MindState.

I have thought about interfaces ... but I didn't have a place for them in Lua!

In my head, interfaces make more sense on closed-structure languages such as C++ or Java. Open-structured languages, such as Lua or Ruby, don't need them so much, since structures are not "closed" - for example, you can add methods to a class any moment you want, not just when creating it.

Mixins make more sense. They are not just "declarations of methods that a class must implement" ... they also have implementation (which the class can then modify). My implementation of mixins is a bit crude (just copy the methods to the class definition, not do much more) but effective.

You can simulate (partially) interfaces by creating a mixing like this:

Code: Select all

MyInterface = {
foo = function(x,y)
end,
bar = function(w,h)
end
}

MyClass = class('MyClass')
MyClass:includes(MyInterface)

I said "partially" because this will only raise an error if you execute MyClass.foo or MyClass.bar. On C++/Java, you will get the error sooner, on the compilation phase. This is a consequence of the fact that Lua structures are open.

I hope this all makes sense.

Just a note: I'll be making an update to MiddleClass soon, separatin the getterSetter stuff to a module (it's already done on the PÄSSION source)

Regards!

EDIT: Oh, and PÄSSION is more like alpha now. Ass soon as I finish the documentation, it can be considered Beta.
When I write def I mean function.

bartbes
Sex machine
Posts: 4946
Joined: Fri Aug 29, 2008 10:35 am
Location: The Netherlands
Contact:

### Re: MiddleClass & MindState: Object Orientation for LUA

Go does interfaces nicely, but the reason why it can do that is because it is a strongly typed language, without the 'almighty' lua tables, I would say that a correct implementation of interfaces in lua is (near) impossible.

kikito
Inner party member
Posts: 3153
Joined: Sat Oct 03, 2009 5:22 pm
Contact:

### Re: MiddleClass & MindState: Object Orientation for LUA

Agreed. The fact that you can make additions to tables in runtime (even creating methods on the fly) kind of defeats the purpose of interfaces, which is to stablish a "contract" on compile time.
When I write def I mean function.

kikito
Inner party member
Posts: 3153
Joined: Sat Oct 03, 2009 5:22 pm
Contact:

### Re: MiddleClass & MindState: Object Orientation for LUA

I've been doing some intense work lately on MiddleClass & MindState.
I use them extensively on PÄSSION; it has reached a point where every little change that I make in any of them can unadvertely "break" other parts. My approach until recently had been "trying the most complex game I have, and see if it works".

But that is tiresome and slow; I've decided to adopt the Test-Driven Phylosophy and wrote a bunch of tests. This is much more systematic than just "running the game and see if something breaks up" and it is also faster - in execution and in bug location, since you see exactly what fails.

MiddleClass' tests, as well as its associated methods (subclassOf, instanceOf, includes, class) has been fully tested and it is quite stable now. MindState is 80% tested.

TDD has helped me track down around 10 bugs; they were mostly edge cases and should not affect most people, but a couple were important enough to mention:
• MiddleClass didn't properly handle metamethods before. Now you can create classes with methods called __add, __mult etc and they will work correctly (they will even be inherited by subclasses, which was surprisingly tricky)
• MindState's popState method has been nearly completely rewritten; it had several bugs on it, mainly related with calling the right callbacks and popping states by name(that didn't work before)
For all this, I recommend you to update your versions of MiddleClass and MindState - download them from github now.
When I write def I mean function.

kikito
Inner party member
Posts: 3153
Joined: Sat Oct 03, 2009 5:22 pm
Contact:

### Re: MiddleClass & MindState: Object Orientation for LUA

I've completed the tests on MindState, and decided to simplify it a bit - I removed an esoteric feature that no one would ever use - states with parameters. Now the states must have an empty constructor, which is the default case and what 100% of the people need anyway.

I'll now proceed to add some mixins to the middleClass lib. These will be completely optional, so they will probably go on an "extra" or "plugins" folder. I still have to decide the name. I might put MindState inside that "extra" folder too.

Regards!
When I write def I mean function.

osuf oboys
Party member
Posts: 215
Joined: Sun Jan 18, 2009 8:03 pm

### Re: MiddleClass & MindState: Object Orientation for LUA

Haha, would be great to see test-driven programming take in LÖVE. How would you handle physics though?
states with parameters. Now the states must have an empty constructor, which is the default case and what 100% of the people need anyway.
Hm, I dont understand this. Is the constructor somehow causing you problems because it seems strange to remove potentially useful functionality that comes for free. I can think of several possible uses, e.g. you have a state for when a button fades from one color to another and you specify the target color upon entering the state. Sure, there are other ways to do it but if has this approach to implement it (i.e. with a state) then the natural thing to do is to pass the color to the constructor.

I've been using Pässion for a toy project. I made a number of changes that I deemed necessary but none to the OOP folder, so I'm happy .
If I haven't written anything else, you may assume that my work is released under the LPC License - the LÖVE Community. See http://love2d.org/wiki/index.php?title=LPC_License.

kikito
Inner party member
Posts: 3153
Joined: Sat Oct 03, 2009 5:22 pm
Contact:

### Re: MiddleClass & MindState: Object Orientation for LUA

Hi Osuf,

I thought like you until I started actually programming the test for that functionality. It is actually very subtle. There are two factors that I need to explain:

1. States need two superclasses

States are classes, with a single modification: super works a bit differently on them - it first looks for methods on the current state's ancestors (just like a regular method does), but when that fails it still has the non-stateful methods to look over. Here's the shortest example I could think of:

Code: Select all

local A = class('A', StatefulObject)
function A:foo() return 'A.foo' end
function A:bar() return 'A.bar' end

function A:foo() return 'AState.foo' end

local B = class('B', A)
local BState = B.states.State
function BState:foo() return super.foo() .. ' from BState' end
function BState:bar() return super.bar() .. ' from BState' end

local b = B:new()
b:gotoState('State')

print(b:foo()) -- AState.foo from BState
print(b:bar()) -- A.bar from BState

I hope this is straightforward enough.

The consequence of all this is that States need 2 superclasses. One is their "Natural" superclass (where super looks first) and then there's the "Non-state" superclass. That's why State.subclass takes 3 parameters instead of two.

The base class is need is subtle: on a stateful method, super works differently than on regular methods. It will look "up" on the state ancestors first, but if

2. referencing the state instance is not possible

That's the other thing - self. It points to the StatefulClass instance (b on the previous example). It never points to the "state instance" in question.

With all this in mind, I concluded that controlling the state instances isn't something the MindState user is expected to do.

Nothing of the above is set in stone, though. I'm always open to new arguments on this.

By the way, you seem to be the only PÄSSION user for the moment. I'd be glad to review those changes you mention.
When I write def I mean function.

kikito
Inner party member
Posts: 3153
Joined: Sat Oct 03, 2009 5:22 pm
Contact:

### Re: MiddleClass & MindState: Object Orientation for LUA

I've commited the latest changes on middleclass to github. The last change contains a not-yet-working version of the Callbacks module. I'm afraid I could not make it work on time before my holidays. I'll do my best to update it after I return. The rest of the code seems to do very nicely, I'm proud to say.

I'll go on holidays now and will not be able to answer questions here until mid-september. I doubt I'll do any forum reading during the next month, but you may try sending me a private message - I might get to read my email more often than the forum.

Regards!
When I write def I mean function.

### Who is online

Users browsing this forum: No registered users and 1 guest