Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cluster generated signals #42

Open
migueldeicaza opened this issue May 1, 2023 · 5 comments
Open

Cluster generated signals #42

migueldeicaza opened this issue May 1, 2023 · 5 comments
Labels
enhancement New feature or request

Comments

@migueldeicaza
Copy link
Owner

Right now to get the ball rolling I just create helper signal classes for each signal.

The signal class could be named after the signal emitted, and in cases where we have clusters of identical parameters, we could try to come up with a name that works. My initial review shows that this would work fine.

Just need time to write the code

@samdeane
Copy link
Contributor

samdeane commented Oct 24, 2024

I think that the signal helper class can be generalised using generics.

Here's a rough mockup:

struct GenericSignal<each T> {
  let name: String

  func emit(_ t: repeat each T) {
    emitSignal(name, repeat each t)
  }

  func connect(callback: @escaping (_ t: repeat each T) -> Void) {
    sp.proxy = { args in
      callback(repeat args.pop(as: (each T).self)!)
    }

    // register proxy with actual signal here...
  }
}


/// A proxy object that can be registered with a signal.
/// When the signal is emitted, the proxy will be called,
/// and will invoke its callback with the supplied arguments.
struct SignalProxy {
  var proxy: ((Arguments) -> Void)? = nil

  func proxyFunc(args: Arguments) {
    proxy?(args)
  }
}

/// A packed array of arguments that can be popped off one by one,
/// with type checking.
class Arguments {
  init(_ args: [Any]) {
    self.args = args
  }

  var args: [Any] = []
  func pop<T>(as: T.Type) -> T? {
    let v = args.first as? T
    args.removeFirst()
    return v
  }
}

@samdeane
Copy link
Contributor

I think that the variadic arguments can be constrained to VariantRepresentable, so that the emit call can just take normal swift types, and the connect closure can receive normal types.

@samdeane
Copy link
Contributor

This should allow us to stop generating any helper classes - we just generate a computed property for each signal which returns a helper.

If this works, then adopting this helper should be a transparent change which doesn't break anything.

The same helper could then be used to implement a cleaner mechanism for declaring signals in Swift (see #584) -- which might be a breaking change.

@samdeane
Copy link
Contributor

Unless this seems like a bad idea, I will experiment with the approach above, and see if I can get it to fly.

Will raise a PR if I get anywhere...

@samdeane
Copy link
Contributor

Implementation done - just testing it a bit...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants