/zoeplat

To get this branch, use:
bzr branch /bzr/zoeplat

« back to all changes in this revision

Viewing changes to zoetrope/core/class.lua

  • Committer: Josh C
  • Date: 2013-03-02 20:40:57 UTC
  • Revision ID: josh@9ix.org-20130302204057-yrra0a51zgtpq2v2
zoetrope 1.3.1

Show diffs side-by-side

added added

removed removed

 
1
-- Class: Class
 
2
-- This is a simple OOP single-inheritance implementation based
 
3
-- on the one suggested by <Programming in Lua at http://www.lua.org/pil/16.html>.
 
4
-- One big difference from what you may be expecting is that there are no
 
5
-- constructors per se; all subclasses share the same constructor method,
 
6
-- which takes a table of properties that are mixed into the instance.
 
7
-- e.g. Code like this:
 
8
--
 
9
-- (begin code)
 
10
-- MyClass = Class:extend{ color = 'red', name = 'robin' }
 
11
-- myObject = MyClass:new{ color = 'blue' }
 
12
-- (end code)
 
13
--
 
14
-- Would set myObject to have a color of 'blue' and a name of 'robin'. There is a
 
15
-- <onNew> event handler you can use to perform initialization based on these values.
 
16
--
 
17
-- Event: onNew
 
18
--              Called once, when a new object is created via <new()>.
 
19
 
 
20
Class = {
 
21
        -- Method: extend
 
22
        -- Creates a subclass of a class object, replacing any class properties
 
23
        -- with those in the object passed. It also sets the subclass's prototype
 
24
        -- property to this class. This alters the passed table in-place.
 
25
        --
 
26
        -- Arguments:
 
27
        --              obj - table of properties
 
28
        --
 
29
        -- Returns:
 
30
        --              subclassed table
 
31
 
 
32
        extend = function (self, obj)
 
33
                obj = obj or {}
 
34
                assert(type(obj) == 'table', 'must extend a table, received a ' .. type(obj))
 
35
        
 
36
                -- copy any table properties into the subclass, so that
 
37
                -- it does not accidentally overwrite them
 
38
                                
 
39
                for key, value in pairs(self) do
 
40
                        if key ~= '__index' and not obj[key] and type(value) == 'table' then
 
41
                                obj[key] = copyTable(self[key])
 
42
                        end
 
43
                end
 
44
                
 
45
                -- __index work to set up inheritance and getters/setters
 
46
 
 
47
                obj = obj or {}
 
48
                setmetatable(obj, self)
 
49
                self.__index = self
 
50
                obj.prototype = self
 
51
                return obj
 
52
        end,
 
53
 
 
54
        -- Method: new
 
55
        -- Extends an object and calls its onNew() handler if it is defined.
 
56
        -- This handler is meant for object-specific initialization,
 
57
        -- not class-wide work.
 
58
        --
 
59
        -- Arguments:
 
60
        --              obj - table of properties that the new object starts with,
 
61
        --                        overriding anything set in the class
 
62
        -- 
 
63
        -- Returns:
 
64
        --              new instance
 
65
        
 
66
        new = function (self, obj)
 
67
                obj = self:extend(obj)
 
68
                if obj.onNew then obj:onNew() end
 
69
                return obj
 
70
        end,
 
71
        
 
72
        -- Method: mixin
 
73
        -- Mixes all properties passed into the current object, overwriting any
 
74
        -- pre-existing values.
 
75
        --
 
76
        -- Arguments:
 
77
        --              obj - table of properties to mix into the object
 
78
        --
 
79
        -- Returns:
 
80
        --              current object
 
81
        
 
82
        mixin = function (self, obj)
 
83
                assert(type(obj) == 'table', 'must mix in a table, received a ' .. type(obj))
 
84
                for key, value in pairs(obj) do
 
85
                        self[key] = obj[key]
 
86
                end
 
87
        end,
 
88
        
 
89
        -- Function: instanceOf
 
90
        -- Checks whether a certain object is anywhere in its inheritance chain.
 
91
        --
 
92
        -- Arguments:
 
93
        --              class - table to check against
 
94
        --
 
95
        -- Returns:
 
96
        --              boolean
 
97
 
 
98
        instanceOf = function (self, class)
 
99
                local proto = self.prototype
 
100
                
 
101
                while proto do
 
102
                        if proto == class then
 
103
                                return true
 
104
                        end
 
105
                        
 
106
                        proto = proto.prototype
 
107
                end
 
108
                
 
109
                return false
 
110
        end
 
111
}