BreakerBox: Bulk-Manage Routine Connections

Hi there,

BreakerBox is a straightforward utility module for bulk connection management and suspension. It increase organization and facilitates better memory management, while remaining distinct from Maid and Janitor classes/implementations.

Roblox library model: https://create.roblox.com/store/asset/16300734843
GitHub repository: GitHub - httpsKingPie/BreakerBox

See in-code documentation or API at the bottom of the thread!

Introduction

BreakerBox is a small utility module in an OOP construct that simplifies connection management and control for connections (in bulk) that frequently reappear yet benefit from periodic interruption. This allows you to manage active connections in a clean and coherent way while also mitigating memory leaks. The module is well-documented and compatible with @evaera’s moonwave.

The best example of this is UI, where lots of connections (e.g.,: MouseEnter, MouseLeave, text changed for scaling, MouseButton1Down, InputEnded, InputBegan, data changed for updating, etc.) either unnecessarily linger (meaning dozens or hundreds of connections exist when the UI itself is not relevant) or require exponentially lengthy code blocks of disconnection logic when temporarily disabling/hiding UI elements (only to reinitialize the connections when applicable [e.g., UI re-opened]).

Concept

Individual BreakerBoxes emulate a fuse box that contains various circuit breakers. When initializing code (continuing with a UI example), create a BreakerBox and add a breaker for the given Signal (compatible with RBXScriptSignals and Signals in pure Lua(u) with a :Connect method), a function that acts as the listener, arguments for said function (optional - these are passed after any arguments that the Signal itself passes when fired). And that’s it! When your connections are no longer needed, simply call BreakerBox:BreakAll() which emulates opening the circuit breaker. When they are needed again, call BreakerBox:Restore() which emulates closing the circuit breaker and restoring electrical flow.

Side note: like a circuit breaker (note, singular ‘a’ circuit breaker, of which multiple can exist within a fuse box) only one connection will be active per Breaker within a BreakerBox. Calling BreakerBox:Restore() multiple times when Breakers are already opened will result in a warning, because Breakers encapsulate and represent a single connection (allowing for toggleable behavior). This prevents duplicate connections from hanging around in your code-base unintentionally.

Comparisons to a Maid/Janitor Class

BreakerBox is specifically designed for connections (managed in bulk) that will return at some point yet benefit from periodic interruption and is built around the idea of reusability. Unlike a Maid or Janitor class, which will execute one-time cleanup code, a BreakerBox provides a tidy method of keeping connections open when necessary and disconnecting them when they are no longer needed. Think of a Maid/Janitor as throwing out the lightbulb when you are done using it, whereas a BreakerBox acts as a light switch - allowing you to toggle on/off with ease.

With that said, for non-connections, connections that cannot be logically considered in bulk, or one-time connections - consider a Maid or Janitor class. BreakerBox is not a philosophically different approach to solving the same problem - it handles a different problem-set entirely.

API Overview

BreakerBoxManager.new() -> [BreakerBox]

Constructor function for creating a new BreakerBox instance.


BreakerBox:AddBreaker(Signal, BoundFunction, Arguments?, OpenBreaker?) -> nil

Parameters:

  • Signal: RBXScriptSignal | Signal
  • BoundFunction: Function
  • Arguments?: Table | nil
  • OpenBreaker?: Boolean | nil

Internally associates the given function and arguments to the provided signal. If OpenBreaker is true, the connection is immediately active; otherwise, it is not connected until BreakerBox:Restore() is called.


BreakerBox:AddBreakersFromArray(Array) -> nil

Parameters:

  • Array: Table

Adds breakers en masse, through a passed array. Array values are dictionaries with the following key pairs: [“Signal”] = RBXScriptSignal | Signal, [“Function”] = function, [“Arguments”] = table | nil, [“OpenBreaker”] = boolean | nil

Example code
local GuiButton: ImageButton = PathToButton

local function OnMouseEnter()
    print("Player is hovering over", GuiButton.Name)
end

local TestArray = {
    ["Signal"] = GuiButton.MouseEnter,
    ["Function"] = OnMouseEnter,
}

BreakerBox:AddBreakersFromArray({
    {
        ["Signal"] = GuiButton.MouseButton1Click,
        ["Function"] = function(...)
            local PassedArguments = {...}
            print("Button clicked:", table.concat(PassedArguments, " ")) -- Expected output: "Button clicked: Yay! Great news!"
        end,
        ["Arguments"] = {"Yay!", "Great news!"},
        ["OpenBreaker"] = false,
    },
    TestArray
})

BreakerBox:BreakAll() -> nil

Description: Disconnects all active connections handled by the BreakerBox.


BreakerBox:Restore() -> nil

Description: Restores all active connections handled by the BreakerBox.

Important note: if OpenBreaker (for :AddBreaker or :AddBreakersFromArray) is not true, then :Restore must be called for the signal to be connected to.

Thanks and let me know if you have any feedback!

5 Likes