lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


As part of a research project, I've written a 3D game engine using only Lua and luaglut.  To make things easier, I've borrowed ideas from pil and implemented C++-ish classes which support multiple inheritence and polymorphism.

Basically, I have a "class" function which generates a new class whenever it is called.  Each class generated by this function can be used to instantiate objects using the __call event.

For example, I can define classes like this:

Vector = class {};

Object = class {
    Position = Vector {0, 0, 0};
    Color = Vector {1, 1, 1, 1};
};

Particle = class {
    Velocity = Vector {0, 0, 0};
    Acceleration = Vector {0, 0, 0};
};


And I can define methods as expected:

function Vector.__add (v1, v2)
    assert (#v1 == #v2, "dim error");
    local r = Vector ();
    for i = 1, #v1 do
        r [i] = v1 [i] + v2 [i];
    end;
    return r;
end;

function Particle:update ()
    self.Position = self.Position + self.Velocity;
end;


Multiple inheritence is also simple, and results in a new class:

ParticleObject = class (Particle, Object);


To instantiate objects with a class, I can just call it:

p = Particle ();
o = Object ();
po = ParticleObject ();


Here is my implementation of the class function:

function class (...)

    local c = {};
    local m = {};
    setmetatable (c, m);

    for i = 1, select ('#', ...) do
        assert (type (select (i, ...)) == "table", 
            "invalid base class specified");

        for k, v in pairs (select (i, ...)) do
            c [k] = v;
        end;
    end;

    c.__index = c;

    function m:__call (obj)

        obj = obj or {};
        setmetatable (obj, c);
        return obj;
    end;

    return c;
end;


The system is reasonably simple and much easier to read than any implementation I've seen recently.  I don't have to worry about :inherit or :new methods, for example.  Also, there is an obvious difference between an object and a class under this system, which for me makes things much easier to understand.

I've tried to make the system as effecient as possible.  Although defining a class requires some iteration, instantiating an object is very fast.

I think this basic idea could be extended and become quite powerful.  Any ideas for improving this system?  Is there another implementation that is inherently faster or more flexible?  Let me know what you think.

Ryanne Thomas Dolan