How to connect() an anonymous handler to an event in Genie? [duplicate] - vala

The Vala Tutorial has an example about DBus using anonymous methods.
Bus.own_name (BusType.SESSION, "org.example.DemoService", /* name to register */
BusNameOwnerFlags.NONE, /* flags */
on_bus_aquired, /* callback function on registration succeeded */
() => {}, /* callback on name register succeeded */
() => stderr.printf ("Could not acquire name\n")); /* callback on name lost */
I am trying to rewrite this code in Genie, but could not manage to convert the two last lines. The Genie Tutorial only has an example on how to use a closure to define an event handler.
f.my_event += def (t, a)
print "event was detected with value %d", a
How do I use anonymous method definitions in a method call with Genie?

I think there is not way. You must call another process using "def".
Bus.own_name (BusType.SESSION, "org.example.DemoService",
BusNameOwnerFlags.NONE,
on_bus_aquired,
reg,
err);
def reg()
pass
def err()
print "error"

This isn't possible at the moment:
https://bugzilla.gnome.org/show_bug.cgi?id=746704
Currently Genie only support the deprecated lambda syntax for signals
(+=). This patch provides lambda support in most constructs, the only
requirement is that braces and parens need to be indent-balanced on
multiple line constructs.

Related

What will this 3rd arg of functions will do where function definition will be there in lua?

I am looking for an explanation of the 3rd argument in uv.tcp_connect and uv.getaddrinfo. How to get the real function name or fun definition? At tcp_connect I saw this third argument as function(err).
function(err) -error is string
At getaddress has 3rd argument.
function(res,err)
Most of the places callback() or function () is calling.
callback() - how to determine this callback is going to call which API ? I know it's all are callback but in my lua code difficult to find fun definition.
I can only guess what you want to know.
uv.tcp_connect(tcp, host, port, callback) callback is -function(err)
This line tells you that the function uv.tcp_connect has four parameters. tcp, host, port and callback.
callback is a function value with one parameter err.
So you would typically do something like this (assuming err is a str
local myCallback = function (err) print("The error is: " .. err) end
uv.tcp_connect(myTcp, myHost, myPort, myCallback)
Or using an anonymous function:
uv.tcp_connect(myTcp, myHost, myPort, function (err) print("The error is: "..err) end)
At some point the program will call your callback and provide the arguments according to the parameter list.

Pausing a stream in dart null safety

I'm converting dart code to nnbd.
I have the following code.
var subscription = response.listen(
(newBytes) async {
/// if we don't pause we get overlapping calls from listen
/// which causes the [writeFrom] to fail as you can't
/// do overlapping io.
subscription.pause();
/// we have new data to save.
await raf.writeFrom(newBytes);
subscription.resume();
});
The problem is I get the following error:
The non-nullable local variable 'subscription' must be assigned before it can be used.
Try giving it an initializer expression, or ensure that it's assigned on every execution path.
I've had a similar problem solved here:
dart - correct coding pattern for subscription when using null saftey?
which was answered by #lrn
However the pattern solution pattern doesn't seem to work in this case.
raf.writeFrom is an async operation so I must use an 'async' method which means I can't use the 'forEach' solution as again I don't have access to the subscription object.
If you really want to use listen, I'd do it as:
var subscription = response.listen(null);
subscription.onData((newBytes) async {
subscription.pause();
await raf.writeFrom(newBytes);
subscription.resume();
});
or, without the async:
var subscription = response.listen(null);
subscription.onData((newBytes) {
subscription.pause(raf.writeFrom(newBytes));
});
which will pause the subscription until the future returned by raf.writeFrom completes (it shouldn't complete with an error, though).
If using listen is not a priority, I'd prefer to use an asynchronous for-in like:
await for (var newBytes in subscription) {
await raf.writeFrom(newBytes);
}
which automatically pauses the implicit subscription at the await and resumes it when you get back to the loop.
Both with stream.listen and the StreamController constructor, null safety has made it nicer to create them first without callbacks, and then add the callbacks later, if the callback needs to refer to the subscription/controller.
(That's basically the same nswer as in the linked question, only applied to onData instead of onDone. You have to pass a default onData argument to listen, but it can be null precisely to support this approach.)
I don't think your code, as written, was legal before null-safety either; you can't reference a variable (subscription) before it's declared, and the declaration isn't complete until after the expression you initialize it with (response.listen(...)) is evaluated. You will need to separate the declaration from the initialization to break the circular dependency:
StreamSubscription<List<int>> subscription;
subscription = response.listen(...);

Provide callback for custom component

I made a custom component which basically wraps a d3 line chart. Now I want to be able to register a callback for clicks on the lines in the chart.
I gave the component a #NgCallback parameter, which I then send events to:
class NetworkSummaryComponent implements NgShadowRootAware {
#NgCallback('callback')
Function callback;
void onShadowRoot(ShadowRoot shadowRoot) {
...
chart.callMethod('listen', ['line-click', (ev) {
var name = ev.callMethod('getLineName');
print(name);
callback({'name': name});
}]);
}
}
When using the component, I specify a function of my controller as callback:
<network-summary
...
callback="ctrl.lineClicked">
</network-summary>
However, that function is never actually called, put I know the callback arrives from the JS side because the print in the first snippet is executed.
If I instead specify the attribute as callback="ctrl.lineClicked()" I get a strange exception:
Closure call with mismatched arguments: function 'call'
I could not find any official documentation on how to properly do callbacks, so I'm not exactly sure what I'm doing wrong.. Any ideas?
It turns out that I had to explicitly name the expected arguments in the attributes:
<network-summary
...
callback="ctrl.lineClicked(name)">
</network-summary>
Hope this is useful to the next person having this problem.

DART: syntax of future then

I don´t understand the syntax of the then() clause.
1. myFuture(6).then( (erg) => print(erg) )
What´s (erg) => expr syntactically?
I thougt it could be a function, but
then( callHandler2(erg)
doesn´t work, Error:
"Multiple markers at this line
- The argument type 'void' cannot be assigned to the parameter type '(String) ->
dynamic'
- Undefined name 'erg'
- Expected to find ')'"
2. myFuture(5).then( (erg) { callHandler(erg);},
onError: (e) => print (e)
What´s `onError: (e) => expr"` syntactically?
3. Is there a difference between the onError: and the .catchError(e) variants?
1) The Fat Arrow is syntactic sugar for short anonymous functions. The two functions below are the same:
someFuture(arg).then((erg) => print(erg));
// is the same as
someFuture(arg).then((erg) { return print(erg); });
Basically the fat arrow basically automatically returns the evaluation of the next expression.
If your callHandler2 has the correct signature, you can just pass the function name. The signature being that it accept the number of parameters as the future will pass to the then clause, and returns null/void.
For instance the following will work:
void callHandler2(someArg) { ... }
// .. elsewhere in the code
someFuture(arg).then(callHandler);
2) See answer 1). The fat arrow is just syntactic sugar equivalent to:
myFuture(5).then( (erg){ callHandler(erg);}, onError: (e){ print(e); });
3) catchError allows you to chain the error handling after a series of futures. First its important to understand that then calls can be chained, so a then call which returns a Future can be chained to another then call. The catchError will catch errors both synchronous and asynchronous from all Futures in the chain. Passing an onError argument will only deal with an error in the Future its an argument for and for any synchronous code in your then block. Any asynchronous code in your then block will remain uncaught.
Recent tendency in most Dart code is to use catchError and omit the onError argument.
I will attempt to elaborate more on Matt's answer, hopefully to give more insights.
What then() requires is a function (callback), whose signature matches the future's type.
For example, given a Future<String> myFuture and doSomething being any function that accepts a String input, you can call myFuture.then(doSomething). Now, there are several ways to define a function that takes a String in Dart:
Function(String) doSomething1 = (str) => /* do something with str */ // only one command
Function(String) doSomething2 = (str) { /* do something with str */ } // several commands
Function(String) doSomething3 = myFunction;
myFunction(String) { // Dart will auto imply return type here
/* do something with str */ // several commands
}
Any of those 3 function definitions (the right hand side of =) could go inside then(). The first two definitions are called lambda functions, they are created at runtime and cannot be reused unless you manually copy the code. Lambda functions can potentially yield language-like expressions, i.e. (connection) => connection.connect(). The third approach allows the function to be reused. Lambda functions are common in many languages, you can read more about it here: https://medium.com/#chineketobenna/lambda-expressions-vs-anonymous-functions-in-javascript-3aa760c958ae.
The reason why you can't put callHandler2(erg) inside then() is because callHandler2(erg) uses an undefined variable erg. Using the lambda function, you will be able to tell then() that the erg in callHandler2(erg) is the output of the future, so it knows where to get erg value.

Callback to Lua member function

I have a lua "animation variable" which has a callback function used in an animation loop.
local av = AnimationVariable(ticker.Position.Y)
...
av:addCallback( ** animation function goes here **)
Skipping over details, this addCallback function is defined as follows in C++:
void LuaUIAnimationVariable::addCallback(luabind::object callback);
and when the animation variable is updated, the callback is executed as such (we call the function with one argument):
luabind::call_function<void>(boost::ref(callback), newValue);
My question is the following: How can I use a member function with addCallback? Assuming I have a Ticker:animate(ypos) function, using addCallback on a Ticker instance addCallBack(ticker:animate) does not compile, and addCallBack(ticker.animate) does not work. I understand that member functions in lua have an implicit "self" first parameter.
Any solution or am I forced to use a global function?
Not sure if I understand your question, but if you mean a Lua member function, you can use a closure:
av:addCallback(function(yval) ticker:animate(yval) end)

Resources