local module = {}
module.__index = module
function module.new(area: Frame)
local self = setmetatable({}, module)
self.bounds = {}
self.bounds.x1 = area.Position.X.Offset
self.bounds.y1 = area.Position.Y.Offset
self.bounds.x2 = area.Position.X.Offset + area.Size.Y.Offset
self.bounds.y2 = area.Position.Y.Offset + area.Size.Y.Offset
self.MouseEnter = Instance.new("BindableEvent").Event
self.MouseExit = Instance.new("BindableEvent").Event
self.MouseHover = Instance.new("BindableEvent").Event
--We DON'T parent these as they are only referenced here and in scripts that require them.
area:Destroy() --scary! we've stored the UDim2 data of the frame and no longer need it (the frame).
return self
end
mouse.Move:Connect(function()
--print(mouse.X, mouse.Y) --DEBUG ONLY
--somehow ref self.bounds and the self.RBXScriptConnection(s) here?
end)
return module
How do I reference the self.bounds object and self.Mouse... instances outside of the module.new() function without setting both as globals?
But moral of the story, you need to pass self into that somehow. Since the function you are trying to use doesn’t have it by default you either have to subscribe to it inside your functions where you keep a local reference of self, or create a self.new() and have its return in a scope (or data structure) visible to your connection.
If you want it to run once, then you would put the module.New in the highest scope (and maybe even directly return that if you are basically doing a Singleton pattern.
But if move needs to effect many things differently, giving each their own move connection inside your .new() is a solid strategy (just make sure you clean them up). Or have a table that holds all the module.new() you make that your connection loops through (still make sure you clean that reference up)
local Module = {}
Module.__index = Module
function Module.new()
local self = setmetatable({}, Module)
self.Value = 5
return self
end
local singleton = Module.new()
mouse.Move:Connect(function()
local self = singleton -- obviously not necessary if you directly use singleton
--blah blah blah code code code
end)
return singleton -- now everything that requests this module has direct access to singleton
--note that this technically still gives me access to self.new(), so it might be better to have new not a part of the Module table if you really are following a singleton pattern.
Internal connection
local Module = {}
Module.__index = Module
function Module.new()
local self = setmetatable({}, Module)
self.Value = 5
self.ConnectionReference = mouse.Move:Connect(function() self:Move() end) -- keep a reference to disconnect in :Destroy().
return self
end
function Module:Move() -- this function has access to self if called, gets hooked up in .new()
print(self.Value) --yay!!!
end
function Module:Destroy()
self.ConnectionReference:Disconnect() -- let us prevent memory leaks
end
return Module
External list (less clean than Internal connection imo, but gets the job done)
local Module = {}
Module.__index = Module
local modules = {} --hold a reference to all active Modules
function Module.new()
local self = setmetatable({}, Module)
self.Value = 5
modules[self] = true --add module as a dictionary key so that the external function can see it's there
return self
end
function Module:Destroy()
modules[self] = nil --removes the dictionary key so as to stop processing it when it no longer exists
end
mouse.Move:Connect(function()
for self, _ in pairs(modules) do
--handle each case, might be best to pcall here to make it so an error in one doesn't stop all of them depending on use case
end
end)
return Module
You can of course slightly mash those together to fit your needs. a move(self) function might be nice instead of directly attaching it to the module if it’s meant to be private for example
i suppose i could also commit a programmer war crime and insert the mouse listener function into the .new() function… not going to be pretty though… I’ll mark your answer as correct and try implementing it your way. Thanks for the help!