Skip to content

Support RBXScriptSignal-Compatible Events #390

@TheNexusAvenger

Description

@TheNexusAvenger

I am trying to use Fusion with a custom button implementation (Nexus Button) that tries to act like a normal instance in terms of property and event passthrough. A quirk of it is that events are custom, but are API-compatible with Roblox events. They exist to provide better typing and to prevent the passed values from being encoded + decoded. With some custom supporting code, the custom buttons can be made to work with Fusion, except for the events.

local NexusButton = ...
local Fusion = ...
local applyInstanceProps = ... --Fusion.Instances.applyInstanceProps

local OnEvent = Fusion.OnEvent

local scope = Fusion.scoped(Fusion, {
    Button = function(scope)
        local button = NexusButton.new()
        return function(properties: Fusion.PropertyTable): TextButton
            table.insert(scope, button) --Scopes support custom :Destroy() methods, which NexusButton has.
            applyInstanceProps(scope, properties, button) --applyInstanceProps works with non-instances. NexusButton acts like one despite not being one.
            return button:GetWrappedInstance() --Returns a TextButton.
        end
    end,
})

local myButton = scope:Button()({
    Name = "MyButton",
    BackgroundColor3 = Color3.fromRGB(255, 255, 255)
    [OnEvent("MouseButton1Down")] = function() --[ERROR] Causes "The TextButton class doesn't have an event called 'MouseButton1Down'." due to not being an RBXScriptSignal.
        print("Clicked!")
    end,
})

Having a non-instance that acts like an instance may or may not be cursed, but it is what I am rolling with. Most of Fusion actually works with it except for 2 aspects:

  • OnEvent does not allow for API-compatible events at all and throws errors.
  • doCleanup doesn't support Disconnect. Destroy is supported, but since RBXScriptConnection does not have that, there isn't an obvious reason to add it.
    • This is fairly easy to work around by mapping Disconnect to Destroy. This is something I can do with a new release, but this might not be a luxury for other people using cursed instance imitation systems.

Both can and have been worked around already (custom OnEvent implementation + store a function to call Disconnect to scope), but I'd be interested in removing the workarounds from my code if I could. I'm also fine with working on a pull request to resolve this if this is something worth addressing.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions