Skip to main content

BaseObject

BaseObject provides interface methods for three core features:

  • Object Destruction via adding a :Destroy() method and IsDestroyed flag property,
  • Task Management across the objects lifetime by providing a janitor internally,
  • and Signal Management by providing interfaces to Register, Get, and Fire signals easily.

Destroy Behavior:

  • When a BaseObject instance is destroyed, it's IsDestroyed property is set to true, and it's Destroyed signal is fired.
  • It's metatable is set to a metatable that will error when any of it's methods or metamethods are called.

You should check IsDestroyed before calling any methods on a BaseObject instance if you are not sure if it has been destroyed or not.

Types

BaseObject

type BaseObject = BaseObject

Properties

ClassName

This item is read only and cannot be modified. Read Only
BaseObject.ClassName: string

Functions

getObjectFromId

static
BaseObject.getObjectFromId(idnumber) → BaseObject?

Fetches the object with the given ID if it exists.

local obj = BaseObject.new()

local id = obj:GetId()

print(BaseObject.getObjectFromId(id) == obj) -- true

isDestroyed

static
BaseObject.isDestroyed(selfBaseObject) → boolean

Checks whether or not the object is destroyed.

local obj = BaseObject.new()

print(BaseObject.isDestroyed(obj)) -- false

obj:Destroy()

print(BaseObject.isDestroyed(obj)) -- true

new

static
BaseObject.new(
tbl{[any]any}?--

Table to construct the BaseObject with

) → BaseObject

Constructs a new BaseObject

local obj = BaseObject.new({
	X = 1,
	Y = 2,
})

obj.Z = 3

print(obj.X, obj.Y, obj.Z) -- 1, 2, 3
local SuperClass = BaseObject

local MyClass = setmetatable({}, SuperClass)
MyClass.__index = MyClass
MyClass.ClassName = "MyClass"

function MyClass.new()
	local self = setmetatable(SuperClass.new(), MyClass)
	-- Custom logic here
	return self
end

function MyClass:Destroy() -- Overwrite the BaseObject Destroy method
	SuperClass.Destroy(self) -- If you overwrite the BaseObject Destroy method you need to have this line to call the original.
end

function MyClass:Print()
	print("Hello, World!")
end

return MyClass

Destroy

BaseObject:Destroy() → ()

Marks the Object as Destroyed, fires the Destroyed Signal, cleans up the BaseObject, and sets the metatable to nil/a special locked MT.

Overriding

If you override this method, you need to make sure you call SuperClass.Destroy(self) to call the superclass methods.

function MyCustomClass:Destroy()
	SuperClass.Destroy(self) -- calls the superclass method to clean up events, tasks, etc..
end

GetId

BaseObject:GetId() → number

Returns the ID of the BaseObject Can be used to fetch the object with BaseObject.getObjectFromId(id)

IsA

BaseObject:IsA(classOrClassName{[any]any} | string) → boolean

Returns true if the given object is of a given class. Takes a class name or class object.

GetTask

BaseObject:GetTask(taskIdany) → Task?

Fetches the task with the given ID if it exists.

local obj = BaseObject.new()

local part = Instance.new("Part")

obj:AddTask(part, nil, "Test")

print(obj:GetTask("Test") == part) -- true

AddTask

BaseObject:AddTask(
taskTask,
taskCleanupMethod(string | true | nil)?,--

(if none is given it will try to infer; Passing true tells it to call it as a function)

taskIdany?
) → Task--

The task that was given

Adds a task to the janitor. If a taskId is provided, it will be used as the key for the task in the janitor and can then be fetched later with :GetTask(). If an ID is provided and there already exists a task with that ID, it will clean up the existing task and then replace the index with the new one. It will return the task that was added/given.

local obj = BaseObject.new()

local task = obj:AddTask(function()
	print("Hello, World!")
end)

obj:Destroy() -- Prints "Hello, World!"

AddPromise

BaseObject:AddPromise(promPromise) → Promise

Adds a promise to the janitor. Similar to :AddTask(). Returns the same Promise that was given to it.

local prom = Promise.delay(math.random(10))

local obj = BaseObject.new()
obj:AddPromise(prom)

task.wait(math.random(10))

obj:Destroy() -- Cancels the promise if it hasn't resolved yet

RemoveTask

BaseObject:RemoveTask(
taskIdany,
dontCleanboolean?
) → ()

Removes a task from the janitor. Cleans the task as if :DoCleaning was called. If dontClean is true, it will not clean up the task, it will just remove it from the janitor.

local obj = BaseObject.new()

local task = obj:AddTask(function()
	print("Hello, World!")
end, nil, "Test")

obj:RemoveTask("Test") -- Prints "Hello, World!"

RemoveTaskNoClean

BaseObject:RemoveTaskNoClean(taskIdany) → ()

Removes a task from the janitor without cleaning it.

local obj = BaseObject.new()

local task = obj:AddTask(function()
	print("Hello, World!")
end, nil, "Test")

obj:RemoveTaskNoClean("Test") -- Does NOT print "Hello, World!"

FireSignal

BaseObject:FireSignal(
signalNamestring,--

The name of the signal to fire

...any--

Arguments to pass to the signal

) → ()

Fires the signal with the given name, if it exists. Equivalent to calling :GetSignal(signalName):Fire(...) except this does not require the signal to exist first.

local obj = BaseObject.new()
local SignalName = "Test"

obj:RegisterSignal(SignalName)

obj:GetSignal(SignalName):Connect(print)

obj:FireSignal(SignalName, "Hello, World!") -- Fires the signal with the argument "Hello, World!"

RegisterSignal

BaseObject:RegisterSignal(
signalNamestring--

Name of signal to register

) → ()

Marks a signal with the given name as registered. Does not actually build a new signal, it sets the index to a SignalMarker to identify it as registered so that it can be fetched later.

HasSignal

BaseObject:HasSignal(signalNamestring) → boolean

Checks whether or not a signal with the given name is registered.

local obj = BaseObject.new()

local SignalName = "Test"

print(obj:HasSignal(SignalName)) -- false

obj:RegisterSignal(SignalName)

print(obj:HasSignal(SignalName)) -- true

GetSignal

BaseObject:GetSignal(signalNamestring) → Signal

Fetches a signal with the given name. Creates the Signal JIT.

ConnectSignal

BaseObject:ConnectSignal(
signalNamestring,
func(...any) → ()
) → ()

Connects a function to a signal with the given name. Creates the signal JIT. Shorthand for :GetSignal(signalName):Connect(func).

GetDestroyedSignal

BaseObject:GetDestroyedSignal() → Signal

Returns a signal that fires when the object is destroyed. Creates the signal JIT. Kept for backwards compatibility.

local obj = BaseObject.new()

obj:GetDestroyedSignal():Connect(function()
	print("Object Destroyed!")
end)

obj:Destroy() -- Prints "Object Destroyed!"

BindToInstance

BaseObject:BindToInstance(
objInstance,
destroyOnNilParentboolean?--

Whether or not to destroy the object when the parent is nil'd

) → function--

Disconnects the binding

Binds the object to the given instance. When the object is destroyed, it will destroy the instance. When the instance is destroyed, it will destroy the object.

local obj = BaseObject.new()
local part = Instance.new("Part")
obj:BindToInstance(part)

do -- setup prints on destroy
	obj:AddTask(function()
		print("Object Destroyed!")
	end)

	part.Destroying:Connect(function()
		print("Part Destroyed!")
	end)
end

local X = if math.random(1,2) == 1 then obj or part
X:Destroy() -- Prints "Object Destroyed!" and "Part Destroyed!" (Destroying one will destroy the other)
Show raw api
{
    "functions": [
        {
            "name": "getObjectFromId",
            "desc": "Fetches the object with the given ID if it exists.\n\n```lua\nlocal obj = BaseObject.new()\n\nlocal id = obj:GetId()\n\nprint(BaseObject.getObjectFromId(id) == obj) -- true\n```",
            "params": [
                {
                    "name": "id",
                    "desc": "",
                    "lua_type": "number"
                }
            ],
            "returns": [
                {
                    "desc": "",
                    "lua_type": "BaseObject?"
                }
            ],
            "function_type": "static",
            "tags": [
                "static"
            ],
            "source": {
                "line": 150,
                "path": "lib/baseobject/src/init.luau"
            }
        },
        {
            "name": "isDestroyed",
            "desc": "Checks whether or not the object is destroyed.\n\n```lua\nlocal obj = BaseObject.new()\n\nprint(BaseObject.isDestroyed(obj)) -- false\n\nobj:Destroy()\n\nprint(BaseObject.isDestroyed(obj)) -- true\n```",
            "params": [
                {
                    "name": "self",
                    "desc": "",
                    "lua_type": "BaseObject"
                }
            ],
            "returns": [
                {
                    "desc": "",
                    "lua_type": "boolean"
                }
            ],
            "function_type": "static",
            "tags": [
                "static"
            ],
            "source": {
                "line": 169,
                "path": "lib/baseobject/src/init.luau"
            }
        },
        {
            "name": "new",
            "desc": "Constructs a new BaseObject\n\n\n\n```lua\nlocal obj = BaseObject.new({\n\tX = 1,\n\tY = 2,\n})\n\nobj.Z = 3\n\nprint(obj.X, obj.Y, obj.Z) -- 1, 2, 3\n```\n\n```lua\nlocal SuperClass = BaseObject\n\nlocal MyClass = setmetatable({}, SuperClass)\nMyClass.__index = MyClass\nMyClass.ClassName = \"MyClass\"\n\nfunction MyClass.new()\n\tlocal self = setmetatable(SuperClass.new(), MyClass)\n\t-- Custom logic here\n\treturn self\nend\n\nfunction MyClass:Destroy() -- Overwrite the BaseObject Destroy method\n\tSuperClass.Destroy(self) -- If you overwrite the BaseObject Destroy method you need to have this line to call the original.\nend\n\nfunction MyClass:Print()\n\tprint(\"Hello, World!\")\nend\n\nreturn MyClass\n```",
            "params": [
                {
                    "name": "tbl",
                    "desc": "Table to construct the BaseObject with",
                    "lua_type": "{[any]: any}?"
                }
            ],
            "returns": [
                {
                    "desc": "",
                    "lua_type": "BaseObject"
                }
            ],
            "function_type": "static",
            "tags": [
                "static"
            ],
            "source": {
                "line": 217,
                "path": "lib/baseobject/src/init.luau"
            }
        },
        {
            "name": "Destroy",
            "desc": "Marks the Object as Destroyed, fires the Destroyed Signal, cleans up\nthe BaseObject, and sets the metatable to nil/a special locked MT.\n:::caution Overriding\nIf you override this method, you need to make sure you call\n`SuperClass.Destroy(self)` to call the superclass methods.\n```lua\nfunction MyCustomClass:Destroy()\n\tSuperClass.Destroy(self) -- calls the superclass method to clean up events, tasks, etc..\nend\n```",
            "params": [],
            "returns": [],
            "function_type": "method",
            "source": {
                "line": 250,
                "path": "lib/baseobject/src/init.luau"
            }
        },
        {
            "name": "GetId",
            "desc": "Returns the ID of the BaseObject\nCan be used to fetch the object with BaseObject.getObjectFromId(id)",
            "params": [],
            "returns": [
                {
                    "desc": "",
                    "lua_type": "number\r\n"
                }
            ],
            "function_type": "method",
            "source": {
                "line": 282,
                "path": "lib/baseobject/src/init.luau"
            }
        },
        {
            "name": "IsA",
            "desc": "Returns true if the given object is of a given class.\nTakes a class name or class object.",
            "params": [
                {
                    "name": "classOrClassName",
                    "desc": "",
                    "lua_type": "{[any]: any} | string"
                }
            ],
            "returns": [
                {
                    "desc": "",
                    "lua_type": "boolean\r\n"
                }
            ],
            "function_type": "method",
            "source": {
                "line": 290,
                "path": "lib/baseobject/src/init.luau"
            }
        },
        {
            "name": "GetTask",
            "desc": "Fetches the task with the given ID if it exists.\n\n```lua\nlocal obj = BaseObject.new()\n\nlocal part = Instance.new(\"Part\")\n\nobj:AddTask(part, nil, \"Test\")\n\nprint(obj:GetTask(\"Test\") == part) -- true\n```",
            "params": [
                {
                    "name": "taskId",
                    "desc": "",
                    "lua_type": "any"
                }
            ],
            "returns": [
                {
                    "desc": "",
                    "lua_type": "Task?"
                }
            ],
            "function_type": "method",
            "source": {
                "line": 322,
                "path": "lib/baseobject/src/init.luau"
            }
        },
        {
            "name": "AddTask",
            "desc": "Adds a task to the janitor. If a taskId is provided, it will be used as the\nkey for the task in the janitor and can then be fetched later with :GetTask().\nIf an ID is provided and there already exists a task with that ID, it will\nclean up the existing task and then replace the index with the new one.\nIt will return the task that was added/given.\n\n```lua\nlocal obj = BaseObject.new()\n\nlocal task = obj:AddTask(function()\n\tprint(\"Hello, World!\")\nend)\n\nobj:Destroy() -- Prints \"Hello, World!\"\n```",
            "params": [
                {
                    "name": "task",
                    "desc": "",
                    "lua_type": "Task"
                },
                {
                    "name": "taskCleanupMethod",
                    "desc": "(if none is given it will try to infer; Passing true tells it to call it as a function)",
                    "lua_type": "(string | true | nil)?"
                },
                {
                    "name": "taskId",
                    "desc": "",
                    "lua_type": "any?"
                }
            ],
            "returns": [
                {
                    "desc": "The task that was given",
                    "lua_type": "Task"
                }
            ],
            "function_type": "method",
            "source": {
                "line": 347,
                "path": "lib/baseobject/src/init.luau"
            }
        },
        {
            "name": "AddPromise",
            "desc": "Adds a promise to the janitor. Similar to :AddTask(). Returns the same Promise\nthat was given to it.\n\n```lua\nlocal prom = Promise.delay(math.random(10))\n\nlocal obj = BaseObject.new()\nobj:AddPromise(prom)\n\ntask.wait(math.random(10))\n\nobj:Destroy() -- Cancels the promise if it hasn't resolved yet\n```",
            "params": [
                {
                    "name": "prom",
                    "desc": "",
                    "lua_type": "Promise"
                }
            ],
            "returns": [
                {
                    "desc": "",
                    "lua_type": "Promise"
                }
            ],
            "function_type": "method",
            "source": {
                "line": 369,
                "path": "lib/baseobject/src/init.luau"
            }
        },
        {
            "name": "RemoveTask",
            "desc": "Removes a task from the janitor. Cleans the task as if :DoCleaning was called.\nIf dontClean is true, it will not clean up the task, it will just remove\nit from the janitor.\n\n```lua\nlocal obj = BaseObject.new()\n\nlocal task = obj:AddTask(function()\n\tprint(\"Hello, World!\")\nend, nil, \"Test\")\n\nobj:RemoveTask(\"Test\") -- Prints \"Hello, World!\"\n```",
            "params": [
                {
                    "name": "taskId",
                    "desc": "",
                    "lua_type": "any"
                },
                {
                    "name": "dontClean",
                    "desc": "",
                    "lua_type": "boolean?"
                }
            ],
            "returns": [],
            "function_type": "method",
            "source": {
                "line": 392,
                "path": "lib/baseobject/src/init.luau"
            }
        },
        {
            "name": "RemoveTaskNoClean",
            "desc": "Removes a task from the janitor without cleaning it.\n\n```lua\nlocal obj = BaseObject.new()\n\nlocal task = obj:AddTask(function()\n\tprint(\"Hello, World!\")\nend, nil, \"Test\")\n\nobj:RemoveTaskNoClean(\"Test\") -- Does NOT print \"Hello, World!\"\n```",
            "params": [
                {
                    "name": "taskId",
                    "desc": "",
                    "lua_type": "any"
                }
            ],
            "returns": [],
            "function_type": "method",
            "source": {
                "line": 413,
                "path": "lib/baseobject/src/init.luau"
            }
        },
        {
            "name": "FireSignal",
            "desc": "Fires the signal with the given name, if it exists.\nEquivalent to calling `:GetSignal(signalName):Fire(...)` except this does not require\nthe signal to exist first.\n\n```lua\nlocal obj = BaseObject.new()\nlocal SignalName = \"Test\"\n\nobj:RegisterSignal(SignalName)\n\nobj:GetSignal(SignalName):Connect(print)\n\nobj:FireSignal(SignalName, \"Hello, World!\") -- Fires the signal with the argument \"Hello, World!\"\n```",
            "params": [
                {
                    "name": "signalName",
                    "desc": "The name of the signal to fire",
                    "lua_type": "string"
                },
                {
                    "name": "...",
                    "desc": "Arguments to pass to the signal",
                    "lua_type": "any"
                }
            ],
            "returns": [],
            "function_type": "method",
            "source": {
                "line": 439,
                "path": "lib/baseobject/src/init.luau"
            }
        },
        {
            "name": "RegisterSignal",
            "desc": "Marks a signal with the given name as registered. Does not actually\nbuild a new signal, it sets the index to a SignalMarker to identify\nit as registered so that it can be fetched later.",
            "params": [
                {
                    "name": "signalName",
                    "desc": "Name of signal to register",
                    "lua_type": "string"
                }
            ],
            "returns": [],
            "function_type": "method",
            "source": {
                "line": 452,
                "path": "lib/baseobject/src/init.luau"
            }
        },
        {
            "name": "HasSignal",
            "desc": "Checks whether or not a signal with the given name is registered.\n\n```lua\nlocal obj = BaseObject.new()\n\nlocal SignalName = \"Test\"\n\nprint(obj:HasSignal(SignalName)) -- false\n\nobj:RegisterSignal(SignalName)\n\nprint(obj:HasSignal(SignalName)) -- true\n```",
            "params": [
                {
                    "name": "signalName",
                    "desc": "",
                    "lua_type": "string"
                }
            ],
            "returns": [
                {
                    "desc": "",
                    "lua_type": "boolean\r\n"
                }
            ],
            "function_type": "method",
            "source": {
                "line": 480,
                "path": "lib/baseobject/src/init.luau"
            }
        },
        {
            "name": "GetSignal",
            "desc": "Fetches a signal with the given name. Creates the Signal JIT.",
            "params": [
                {
                    "name": "signalName",
                    "desc": "",
                    "lua_type": "string"
                }
            ],
            "returns": [
                {
                    "desc": "",
                    "lua_type": "Signal"
                }
            ],
            "function_type": "method",
            "source": {
                "line": 489,
                "path": "lib/baseobject/src/init.luau"
            }
        },
        {
            "name": "ConnectSignal",
            "desc": "Connects a function to a signal with the given name. Creates the signal JIT.\nShorthand for `:GetSignal(signalName):Connect(func)`.",
            "params": [
                {
                    "name": "signalName",
                    "desc": "",
                    "lua_type": "string"
                },
                {
                    "name": "func",
                    "desc": "",
                    "lua_type": "(...any) -> ()"
                }
            ],
            "returns": [],
            "function_type": "method",
            "source": {
                "line": 510,
                "path": "lib/baseobject/src/init.luau"
            }
        },
        {
            "name": "GetDestroyedSignal",
            "desc": "Returns a signal that fires when the object is destroyed. Creates the signal JIT.\nKept for backwards compatibility.\n\n```lua\nlocal obj = BaseObject.new()\n\nobj:GetDestroyedSignal():Connect(function()\n\tprint(\"Object Destroyed!\")\nend)\n\nobj:Destroy() -- Prints \"Object Destroyed!\"\n```",
            "params": [],
            "returns": [
                {
                    "desc": "",
                    "lua_type": "Signal\r\n"
                }
            ],
            "function_type": "method",
            "source": {
                "line": 528,
                "path": "lib/baseobject/src/init.luau"
            }
        },
        {
            "name": "BindToInstance",
            "desc": "Binds the object to the given instance. When the object is destroyed, it will\ndestroy the instance. When the instance is destroyed, it will destroy the object.\n\n```lua\nlocal obj = BaseObject.new()\nlocal part = Instance.new(\"Part\")\nobj:BindToInstance(part)\n\ndo -- setup prints on destroy\n\tobj:AddTask(function()\n\t\tprint(\"Object Destroyed!\")\n\tend)\n\n\tpart.Destroying:Connect(function()\n\t\tprint(\"Part Destroyed!\")\n\tend)\nend\n\nlocal X = if math.random(1,2) == 1 then obj or part\nX:Destroy() -- Prints \"Object Destroyed!\" and \"Part Destroyed!\" (Destroying one will destroy the other)\n```",
            "params": [
                {
                    "name": "obj",
                    "desc": "",
                    "lua_type": "Instance"
                },
                {
                    "name": "destroyOnNilParent",
                    "desc": "Whether or not to destroy the object when the parent is nil'd",
                    "lua_type": "boolean?"
                }
            ],
            "returns": [
                {
                    "desc": "Disconnects the binding",
                    "lua_type": "function"
                }
            ],
            "function_type": "method",
            "source": {
                "line": 568,
                "path": "lib/baseobject/src/init.luau"
            }
        }
    ],
    "properties": [
        {
            "name": "ClassName",
            "desc": "",
            "lua_type": "string",
            "readonly": true,
            "source": {
                "line": 134,
                "path": "lib/baseobject/src/init.luau"
            }
        }
    ],
    "types": [
        {
            "name": "BaseObject",
            "desc": "",
            "lua_type": "BaseObject",
            "source": {
                "line": 128,
                "path": "lib/baseobject/src/init.luau"
            }
        }
    ],
    "name": "BaseObject",
    "desc": "BaseObject provides interface methods for three core features:\n- Object Destruction via adding a :Destroy() method and IsDestroyed flag property,\n- Task Management across the objects lifetime by providing a janitor internally,\n- and Signal Management by providing interfaces to Register, Get, and Fire signals easily.\n\n\nDestroy Behavior:\n* When a BaseObject instance is destroyed, it's `IsDestroyed` property is set to true, and it's `Destroyed` signal is fired.\n* It's metatable is set to a metatable that will error when any of it's methods or metamethods are called.\n\nYou should check `IsDestroyed` before calling any methods on a BaseObject instance if you are not sure if it has been destroyed or not.",
    "source": {
        "line": 19,
        "path": "lib/baseobject/src/init.luau"
    }
}