Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- BaseClass = {
- -- if you're doing static methods, this would be one
- new = function(self)
- -- Obviously all this stuff won't have to be written each time, but instead embeded in the language
- local newRaw = {} -- the object with the actual values in it
- setmetatable(newRaw, { __index = self })
- -- these are to prevent infinite loops in getters and setters (so, for example, doing self.speed = 10 in setSpeed doesn't cause setSpeed to be called a million times)
- local lockedSetters = {}
- local lockedGetters = {}
- local newProxy = {} -- the proxy. 'self' always needs to be this, NOT newRaw
- setmetatable(newProxy, {
- __index = function(t, k)
- -- just an idea, see the set and get functions
- -- this basically allows a global filter or notification on all get
- if not lockedGetters[k] and newRaw.get and type(newRaw.get) == 'function' then
- lockedGetters[k] = true
- local use, value = newRaw.get(newProxy, k)
- lockedGetters[k] = nil
- if use then
- return value
- end
- end
- -- basically, if the get'Key' function is set, return it's value
- -- names are capitalised, so .name becomes getName; This might cause a few issues regarding collisions, but really, how many (good) coders are using .name and .Name
- -- non-function properties can't use it, because, well, it's just futile really
- local getFunc = 'get' .. k:sub(1, 1):upper() .. k:sub(2, -1)
- if not lockedGetters[k] and type(newRaw[k]) ~= 'function' and newRaw[getFunc] and type(newRaw[getFunc]) == 'function' then
- lockedGetters[k] = true
- local value = newRaw[getFunc](newProxy)
- lockedGetters[k] = nil
- return value
- else
- return newRaw[k] -- return the raw value if not using the getter
- end
- end,
- __newindex = function (t,k,v)
- -- just an idea, see the set and get functions
- -- this basically allows a global filter or notification on all sets
- if not lockedSetters[k] and type(newRaw.set) and type(newRaw.set) == 'function' then
- lockedSetters[k] = true
- local use, value = newRaw.set(newProxy, k, v)
- lockedSetters[k] = nil
- if use then
- newRaw[k] = value
- return
- end
- end
- -- if the filter wasn't applied, if the set'Key' function is set, call it
- local setFunc = 'set' .. k:sub(1, 1):upper() .. k:sub(2, -1)
- if not lockedSetters[k] and type(newRaw[k]) ~= 'function' and newRaw[setFunc] and type(newRaw[setFunc]) == 'function' then
- lockedSetters[k] = true
- newRaw[setFunc](newProxy, v) -- see the comment for newRaw[getFunc](newRaw) regarding the use of newRaw
- lockedSetters[k] = nil
- -- alternate way of doing it, return the value instead of setting it
- -- newRaw[k] = newRaw[setFunc](newRaw, v) -- see the comment for newRaw[getFunc](newRaw) regarding the use of newRaw
- else
- newRaw[k] = v -- use the passed value if not using the setter
- end
- end
- })
- -- use the setters with all the starting values
- for k, v in pairs(self) do
- if type(self[k]) ~= 'function' then
- newProxy[k] = v
- end
- end
- return newProxy
- end
- }
- Person = {
- name = 'Default Name', -- doesn't actually have to be set, but this acts as a default
- -- again, not sure about the naming convention here. the __ looked ugly really, although it did kinda make sense.
- setName = function(self, name)
- -- for example, let's capitalise the name
- -- I'm not sure if returning of setting the name is better than this though (see the comment in __newindex)
- self.name = name:sub(1, 1):upper() .. name:sub(2, -1)
- end,
- getName = function(self)
- -- and then tack an underscore on the front for the sake of it
- if self.name and #self.name > 0 then
- return '_' .. self.name
- end
- end,
- set = function(self, key, value)
- -- we don't want to set the value, return false.
- -- these functions doesn't actually need to be here in this example, but may be useful for things such as UI updates when any of the values (text, colour, etc.) change
- return false
- end,
- get = function(self, key)
- -- we don't want to alter the returned value, return false
- return false
- end,
- }
- -- you'd obviously automate this bit
- setmetatable(Person, { __index = BaseClass })
- -- example where both aren't required
- Car = {
- speed = 0, -- can poetentially be false
- speedLimit = 5,
- -- again, not sure about the naming convention here. the __ looked ugly really, although it did kinda make sense.
- setSpeed = function(self, speed)
- -- don't go speeding there mate!
- self.speed = math.min(speed, self.speedLimit)
- end,
- getSpeedLimit = function(self)
- -- for example, moving through different roads and detecting the limit from GPS
- local i = math.ceil(math.random() * 3)
- local limits = { 30, 50, 100 }
- return limits[i]
- end
- }
- setmetatable(Car, { __index = BaseClass })
- -- example where the globals are used
- Button = {
- x = 2,
- y = 10,
- text = 'Click Me',
- backgroundColour = colours.blue,
- width = 1,
- -- US spelling catchers. YAY!
- setBackgroundColor = function(self, color)
- self.backgroundColour = color
- end,
- getBackgroundColor = function(self)
- return self.backgroundColour
- end,
- setText = function(self, text)
- self.width = #text + 2
- self.text = text
- end,
- set = function(self, key, value)
- self:draw()
- -- again, we don't actually want to edit the value, simply know when any of them were changed
- return false
- end,
- draw = function(self)
- -- haven't done this for simplicity, but given the right setup with a draw queue (because this would get called a lot more than it would actually need to be redraw) it would work 100%
- end
- }
- setmetatable(Button, { __index = BaseClass })
- -- Ideally you couldn't do Person.Name (instance function), only static functions on Person. It's not essential though
- local oeed = Person:new()
- oeed.name = 'oeed'
- print(oeed.name) -- _Oeed
- local sportsCar = Car:new()
- sportsCar.speed = 120
- print(sportsCar.speed) -- 30, 50 or 100
- sportsCar.speed = 40
- print(sportsCar.speed) -- 30 or 40
- local button = Button:new()
- -- the button would be draw without any other work
- button.text = 'I am a rather wide button!'
- button.y = 20
- -- the button would now appear wide, with that text and at y = 20
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement