From afac3fdc7ce03e03304eec448149f346099cab94 Mon Sep 17 00:00:00 2001 From: Aki Date: Fri, 26 May 2017 15:30:27 +0200 Subject: Added Object.lua to lib --- lib/Object.lua | 77 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 77 insertions(+) create mode 100644 lib/Object.lua 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 -- cgit v1.1