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

Callback forwarding #111

Closed
ogoffart opened this issue Nov 23, 2020 · 6 comments
Closed

Callback forwarding #111

ogoffart opened this issue Nov 23, 2020 · 6 comments
Labels
rfc Request for comments: proposals for changes

Comments

@ogoffart
Copy link
Member

Usually, one want to just forward a signal from the component to the parent.
Suggestions:

  • Do nothing: so we have to declare a signal and forward it:
App := Window {
   signal button_clicked;
   Button { clicked => { root.button_clicked();  } }
}

Perhaps the syntax could be made easier by allowing to omit the { }?

  • Use the same syntax as for properties:
App := Window {
   signal button_clicked <=> but.clicked;
   but := Button {  }
}
// or
App := Window {
   signal button_clicked;
   but := Button { clicked <=> root.button_clicked  }
}
  • Somehow have a new syntax to automatically create a signal on the root
App := Window {
    Button {  
        // automatically create a signal
        forward clicked as button_clicked;
    }
}
@ogoffart ogoffart added the rfc Request for comments: proposals for changes label Nov 23, 2020
@jturcotte
Copy link
Contributor

jturcotte commented Nov 23, 2020

From a quick glance I like signal button_clicked <=> but.clicked;. It's consistent with the two-way properties and allows renaming the signal.

Just clicked <=> root.button_clicked looks a bit confusing.

One thing that makes it weird though is that the signal isn't two ways, so the correct way to express it maybe be signal button_clicked <= but.clicked; ?

edit: In those cases, one question is what would happen if you try to emit button_clicked() directly?

@jturcotte
Copy link
Contributor

Perhaps the syntax could be made easier by allowing to omit the { }?

About this, since you basically want to assign a function as a function property (signal handler), it could maybe be simplified further by removing parentheses too:

App := Window {
   signal button_clicked;
   Button { clicked: root.button_clicked }
}

Or maybe:

App := Window {
   signal button_clicked;
   Button { clicked => root.button_clicked }
}

If you ever allow native functions to be imported in the .60 file, the same syntax could be used to assign the native function directly as a signal handler instead of wrapping it with a pass-through lambda expression (if the signature allows it, the lambda at least allows adapting a callee with a slightly different signature).

@tronical
Copy link
Member

tronical commented Nov 30, 2020

Subsequent discussion produced another angle. Signal forwarding here might serve the purpose of addressing a bigger problem:

It may be desirable to write re-usable compoments in .60 where some aspects are handled by native code. A "Piano Key" would be an example, that when pressed should use system APIs to produce the correct note. All the information to accomplish the task may be available inside the "Piano Key" and the API for producing the sound may not require any additional state, i.e. just have a "beep(frequency)" type of global function.

In that scenario it seems overkill to use signal forwarding and it would feel more natural if it were possible to declare that for the component in question ("Piano Key") should be able to call a function that's implemented in Rust, C++ or perhaps even JavaScript.

Here's an example of a draft syntax:

export PianoKey := Rectangle {
    property <int> note;

    extern function play_note(note: int); // Must be implemented in Rust, C++ or JavaScript

    ....
    Button := {
        clicked => {
            play_note(root.note);
        }
    }
}

The example is incomplete, but demonstrates the direction that might be worth taking instead of further encouraging the signal forwarding.

@ogoffart ogoffart added this to Needs triage in Issue priorities via automation Feb 2, 2021
@ogoffart ogoffart moved this from Needs triage to Low priority in Issue priorities Feb 2, 2021
@ogoffart
Copy link
Member Author

ogoffart commented Feb 2, 2021

Another possibility is to use global singleton
#96
and have a callback in the singleton.

@ogoffart ogoffart changed the title Signal forwarding Callback forwarding Jun 1, 2021
ogoffart added a commit that referenced this issue Jun 7, 2021
ogoffart added a commit that referenced this issue Jun 7, 2021
@ogoffart
Copy link
Member Author

With #96 being closed, i think i can close this as the solution is just to forward to a global callback.

Issue priorities automation moved this from Low priority to Closed Aug 27, 2021
@ogoffart
Copy link
Member Author

ogoffart commented Aug 27, 2021

So, to take the earlier example from an earlier comment, this is how we can now do it:

export global PianoLogic := {
    callback play_note(int); 
}

export PianoKey := Rectangle {
    property <int> note;
    // ...
    Button {
        clicked => {
            PianoLogic.play_note(root.note);
        }
    }
}

Then in rust:

application.global::<PianoLogic>().on_play_node(|note: i32| {/*... */});

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
rfc Request for comments: proposals for changes
Projects
Development

No branches or pull requests

3 participants