summaryrefslogtreecommitdiffhomepage
path: root/lib/Object.lua
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Object.lua')
-rw-r--r--lib/Object.lua77
1 files changed, 77 insertions, 0 deletions
diff --git a/lib/Object.lua b/lib/Object.lua
new file mode 100644
index 0000000..b241bb2
--- /dev/null
+++ b/lib/Object.lua
@@ -0,0 +1,77 @@
+--- You may not believe me but we are not returning this one.
+-- This table is used as metatable for classes e.g. for `Object`.
+local Class = {}
+
+--- Metamethod for classes.
+-- Creates new instance of class calling `new()` method (constructor) with all parameters passed.
+Class.__call = function (self, ...)
+ local o = setmetatable({}, self)
+ self.new(o, ...)
+ return o
+end
+
+--- Metamethod for classes.
+-- First checks if `__index` (instance prototype) have field we are looking for. Then it tries to find it in super class.
+Class.__index = function (self, key)
+ if rawget(self, "__index") ~= nil then
+ if rawget(self, "__index")[key] ~= nil then
+ return rawget(self, "__index")[key]
+ end
+ end
+ if rawget(self, "__super") ~= nil then
+ if rawget(self, "__super")[key] ~= nil then
+ return rawget(self, "__super")[key]
+ end
+ end
+ return nil
+end
+--- Metamethod for classes.
+-- Redirects creating new properties to class'es `__index` which is used as a prototype for instances of class.
+-- Only `new` method and metamethods are allowed to be written to class'es table directly.
+Class.__newindex = function(self, key, value)
+ if key == "new" or key:sub(1, 2) == "__" then
+ rawset(self, key, value)
+ else
+ self.__index[key] = value
+ end
+end
+
+--- Creates new class from parent class.
+-- New class will call parent's constructor unless new constructor will be defined.
+-- @param parent super class of new class
+local extends = function (parent)
+ local self = setmetatable({}, Class)
+ rawset(self, "__index", {})
+ if parent then
+ setmetatable(self.__index, {__index = parent.__index})
+ end
+ rawset(self, "__super", parent)
+ return self
+end
+
+--- Almost empty class.
+-- Used to create new classes via `extend()` method:
+-- `Child = Object:extend()`
+-- Contains `is()` and `new()` methods. Later one isn't available from inside of instances.
+local Object = extends(nil)
+rawset(Object, "extends", extends)
+Object.new = function (self) end
+
+--- Checks if class or instance of class is a child of class passed through parameter.
+-- @param class table we want to test against (preferably class table)
+-- @return boolean which is false if tested sample is not child of passed class
+function Object:is (class)
+ if not class then return false end
+ if self == class or getmetatable(self) == class then
+ return true
+ end
+ if self.__super then
+ return self.__super:is(class)
+ end
+ if getmetatable(self).__super then
+ return getmetatable(self).__super:is(class)
+ end
+ return false
+end
+
+return Object