Skip to content

Instantly share code, notes, and snippets.

@Quenty
Created September 24, 2017 17:41
Show Gist options
  • Save Quenty/b8538b98448ef658335397967d8358a4 to your computer and use it in GitHub Desktop.
Save Quenty/b8538b98448ef658335397967d8358a4 to your computer and use it in GitHub Desktop.

This is basically a Roblox OOP system that I've been using.

The documentation is in LuaDoc, and is sometimes included

First module:

--- Represents a basic class
local Class = {}
Class.__index = Class
Class.ClassName = "Class" -- I set a ClassName in the metatable to make debugging easier and to make it clear this is a class

--- Constructs a new class
-- @param Arg1 First argument in constructor
-- @param Arg2 Second argument, these are optional
local function Class.new(Arg1, Arg2)
  local self = setmetatable({}, Class)
  
  self.Arg1 = Arg1 or error("No Arg1")
  self.Arg2 = Arg2 or error("No Arg2")
  
  return self
end

--- Getter to retrieve arg1
-- @return Arg1
function Class:GetArg1()
  return self.Arg1
end

--- Private methods are indicated using _ as inspired by Doug
-- @return Sum of components
function Class:_sum()
  return self.Arg1 + self.Arg2
end

--- Retrieves the sum for the class
function Class:GetSum()
  return self.Sum or error("No sum calculated")
end

--- Recalculates all values
function Class:Recalculate()
  self.Sum = self:_sum()
  
  if self.Resource then
    self.Sum = self.Sum + self.Resource:GetSum()
end

-- Sets a resource in a class, lets me chain things (see dependency injection)
function Class:WithResource(Resource)
  self.Resource = Resource or error("No resource")
    
  return self
end

return Class

Another module:

local ReplicatedStorage = game:GetService("ReplicatedStorage")

local NevermoreEngine   = require(ReplicatedStorage:WaitForChild("NevermoreEngine"))
local LoadCustomLibrary = NevermoreEngine.LoadLibrary

local Class = LoadCustomLibrary("Class") -- Using Nevermore, you can load however you want

--- An inherited class
local ChildClass = setmetatable({}, Class)
ChildClass.__index = ChildClass
ChildClass.ClassName = "ChildClass"

--- Construct a child class which inherits from class
-- @param Arg1 First argument in constructor
-- @param Arg2 Second argument, these are optional
-- @param Arg3 Third argument, this one is used for 
function ChildClass.new(Arg1, Arg2, Arg3)
  local self = setmetatable(Class.new(Arg1, Arg2), ChildClass)
  
  self.Arg3 = Arg3 or error("No Arg3") -- Sanity check
  self:Recalculate()
  
  return self
end

--- Retrieves the sum for the class
function ChildClass:GetSum()
  return self.TotalSum or error("No sum calculated")
end

function ChildClass:Recalculate()
  local Super = getmetatable(ChildClass)
  
  -- Call super class calculation
  Super.Recalculate(self)
  
  -- Calculate total sum
  self.TotalSum = self.Sum + self.Arg3
end

return ChildClass

Main script:

local ReplicatedStorage = game:GetService("ReplicatedStorage")

local NevermoreEngine   = require(ReplicatedStorage:WaitForChild("NevermoreEngine"))
local LoadCustomLibrary = NevermoreEngine.LoadLibrary

local ChildClass = LoadCustomLibrary("ChildClass") -- Using Nevermore, you can load however you want
local Class = LoadCustomLibrary("Class")

local Object = ChildClass.new(5, 10, 15)
  :WithResource(Class.new(5, 10)) -- Inject resource into the object

print(Object:GetSum())

I didn't test this code, so let me know if it works.

@Quenty
Copy link
Author

Quenty commented Jan 17, 2018

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment