From 169599f86cc0b1983c8af89e4a72fb71aa93a974 Mon Sep 17 00:00:00 2001 From: Paul Liverman III Date: Mon, 14 Aug 2017 06:02:36 -0700 Subject: [PATCH] added Lua-based MoonScript-compatible class system #28 --- class.lua | 21 +++++++++++++++++++-- class.moon | 39 +++++++++++++++++++-------------------- config.ld | 6 ++++++ tmp.class.usage.lua | 18 +++++++++++++++--- 4 files changed, 59 insertions(+), 25 deletions(-) diff --git a/class.lua b/class.lua index c36a22e..db7f617 100644 --- a/class.lua +++ b/class.lua @@ -1,5 +1,5 @@ local Class -Class = function(name) +Class = function(name, parent) local newClass, base base = { __index = base, @@ -16,6 +16,23 @@ Class = function(name) return self end }) - return newClass + if parent then + setmetable(base, { + __parent = parent.__base + }) + newClass.__parent = parent + newClass.__index = function(cls, name) + local val = rawget(base, name) + if val == nil then + return parent[name] + else + return val + end + end + if parent.__inherited then + parent:__inherited(newClass) + end + end + return newClass, base end return Class diff --git a/class.moon b/class.moon index 741d69e..1c38a6a 100644 --- a/class.moon +++ b/class.moon @@ -1,7 +1,5 @@ --- basically, gonna use the knowledge of how MoonScript classes work to make --- something that does the same thing using syntax similar to MiddleClass - -Class = (name) -> +--- @todo document this! +Class = (name, parent) -> local newClass, base base = { __index: base @@ -19,21 +17,22 @@ Class = (name) -> return @ } - return newClass + if parent + setmetable base, { + __parent: parent.__base + } + + newClass.__parent = parent + newClass.__index = (cls, name) -> + val = rawget(base, name) + if val == nil + return parent[name] + else + return val + + if parent.__inherited + parent\__inherited newClass + + return newClass, base return Class - --- base obj with an __index to itself, contains functions accepting a self argument, --- and __class pointing to class obj --- --- class is obj w __init function, __base linking to base obj, and __name specifying name of class --- it has metatable, __index is the base table (makes perfect sense), --- __call is a function that creates a self obj w the base obj as a metatable, then calls __init --- on it, and returns the self (__init is never meant to get directly called) --- --- inheritance addtionally does: --- --- new base obj will have a metatable set to parent.__base (where parent is parent class obj) --- new class obj will have __parent value linking to parent class obj, and __index metamethod --- that returns rawget(new base, name) or return parent class[name] if that was nil --- if parent class had __inherited, then is called w parent class and new class diff --git a/config.ld b/config.ld index 97489bd..e580bf0 100644 --- a/config.ld +++ b/config.ld @@ -1,10 +1,16 @@ file = { "init.moon", "elements/box.moon", + "elements/button.moon", + "elements/dynamicGrid.moon", "elements/element.moon", + "elements/grid.moon", + "elements/scrollbox.moon", "elements/text.moon", "elements/window.moon", "extensions/streamlined_get_set.moon", + "extensions/utility.moon", + "class.moon", "main.moon", "util.moon", "Element.luadoc", diff --git a/tmp.class.usage.lua b/tmp.class.usage.lua index 6431fab..0d3c68f 100644 --- a/tmp.class.usage.lua +++ b/tmp.class.usage.lua @@ -1,12 +1,24 @@ -local class = require "Class" +local class = require "class" -local Car = class("Car") +local Car, CarBase = class("Car") function Car:__init(x, y) self.x = x or 0 self.y = y or 0 end -function Car:print() -- this will be broken +function CarBase:print() -- this will be correct print("I'm a car, at ("..self.x..","..self.y..")") end + +local Motorcycle, MotorcycleBase = class("Motorcycle", Car) + +function Motorcycle:__init(x, y) + Car.__init(self, x, y) -- if you want to use a parent's constructor, you must manually call it + + -- do additional stuff or whatever +end + +function MotorcycleBase:someFunc() + -- do whatever to an instance +end