Is it possible to pass a function with SignalR? - javascript

I imagine it would look like the following.
Server(C#):
public class MyHub : Hub {
...
public int DoSomething(Func<int> fn) {
var res = fn();
return res;
}
...
}
Client(TS/JS):
myHub.invoke('DoSomething', () => 2 + 2).then(res => console.log(res));
However, with this code fn is null on the server.

Seems this is impossible as your parameters should be serializable. So all you can - serialize parameters in known structure and generate invocation function based on deserialization result.

You could write the function in c# and pass it back to the server as a string, then compile and run it - this might help with compiling:
http://www.codeproject.com/Tips/715891/Compiling-Csharp-Code-at-Runtime

Related

Why I can't execute Java method in JavaScript code?

Please have a look at the JavaScript code below.
const locations = /*[[${locations}]]*/ null;
locations.forEach(location => {
location.description = 44;
location.lnglat = 127;
location.fun(); // error
});
description and lnglat are variables from Java list of objects of class 'Location'; fun is a function from this class.
There is no problem assigning values to variables, but I can't call the function fun. Unfortunately, I don't know what the reason is and how can I fix it.
In Java, I use Spring Boot and method addAttribute:
#GetMapping("/")
public String homePage(Model model) {
model.addAttribute("locations", locations());
return "home";
}

Haxe Macros - replace "function" with "async function"

I want that when converting haxe to JavaScript, asynchronous is added to its methods.
I have Haxe code:
#:expose
class Main implements IAsync {
static function main() {
trace("test");
}
static function testAwait() {
return 1;
}
}
And this code is converted to such a code:
. . .
Main.testAwait = function() {
return Main.test();
};
. . .
I wanted to be able replace function to async function in this code.
For example:
Main.testAwait = async function() {
return Main.test();
};
But I can only change the name of the method for example code macros:
package haxe_test;
import haxe.macro.Expr;
import haxe.macro.Context;
using haxe.macro.Tools;
using haxe_test.AsyncBuilder;
class BuildHub {
macro static public function build():Array<Field> {
var fields = Context.getBuildFields();
var testFunc:Function = {
expr: macro return $v{1},
ret: null,
params: [],
args: []
};
fields.push({
name: "testAwait",
access: [Access.AStatic],
kind: FieldType.FFun(testFunc),
pos: Context.currentPos(),
});
return fields;
}
How replace function to async function?
UPD: I simplified code. Maybe is anythings options compilers or JSGenApi can help me)?
Not sure if you considered something more simple but in Haxe 4 you can do something like this:
class Test {
static function main() {
var value = await( async(testAsync) );
trace(value);
}
static function testAsync() return 1;
static inline function await<T>(fn:Void->Void):T {
return js.Syntax.code("await {0}()", fn);
}
static inline function async<T>(fn:Void->Void):T {
return js.Syntax.code("async () => {0}()", fn);
}
}
or do both at same time:
class Test {
static function main() {
var value = asyncAwait( testAsync );
trace(value);
}
static function testAsync() return 1;
static inline function asyncAwait<T>(fn:Void->Void):T {
return js.Syntax.code("(async () => { await {0}() })()", fn);
}
}
I think your general options would be:
Collect information about async types/fields in build macros, then use that in haxe.macro.Context.onAfterGenerate to modify the output file. Since Haxe code is consistently indented, you can get away with a couple regular expressions (I once made a macro that'd split the output file into multiple by-package files this way).
Make a slightly modified copy of haxe.macro.ExampleJSGenerator to prepend async before method declarations of interest. Since you do not need any changes to expression printing, this is also pretty easy.

Creating javascript hooks possible?

Is it possible to create a hook system in javascript as like as php ?
for an example ----
function myjsfunction(){
call_my_function('handle_name');
}
now whatever function people add with 'handle' name it should get executed there.
like
add_to_function('handle_name', function(){alert('hi')});
add_to_function('handle_name', function(){alert('hello')});
both these functions should execute
var hooks = {};
function add_to_function(name, func) {
if(!hooks[name]) hooks[name] = [];
hooks[name].push(func);
}
function call_my_function(name, ...params){
if(hooks[name])
hooks[name].forEach(func => func(...params));
}
As functions are first class in js you can simply store them in an object.
Usecase:
add_to_function("log", console.log.bind(console, "this will log "));
call_my_function("log", "sth cool!");
Implementation with an IIFE:
http://jsbin.com/joxigabeyi/edit?console

JS - modular programing

I want to set up a manager with a handler object that provides a specific function for each request. Why is only syntax a) working in other sample code I saw syntax b)
a)
my.manager.requesthandler.create();
.
b)
my.manager.requesthandler [create]();
.
// my manager-modul
(function(){
my.manager = (function(){
var requesthandler = {
create: function () {
//do something
}
};
return {
requesthandler : requesthandler
};
})();
})();
my.manager.requesthandler.create
is equivalent to
my.manager.requesthandler["create"]
(notice the quotation marks)
what you wrote as b
my.manager.requesthandler[create]
means looking up a variable named create and getting
my.manager.requesthandler["whatever string create's value is"]

Passing JS function to Emscripten-generated code

I have a piece of C++ code converted to JavaScript via Emscripten. I would like the converted C++ code to call back to the JavaScript code that calls it. Something like:
JavaScript:
function callback(message) {
alert(message);
}
ccall("my_c_function", ..., callback);
C++:
void my_c_function(whatever_type_t *callback) {
callback("Hello World!");
}
Is this possible somehow?
I believe the accepted answer is a bit outdated.
Please refer to this bullet point in the "Interacting with code" emscripten tutorial.
E.g.
C:
void invoke_function_pointer(void(*f)(void)) {
(*f)();
}
JS:
var pointer = Runtime.addFunction(function() {
console.log('I was called from C world!');
});
Module.ccall('invoke_function_pointer', 'number', ['number'], [pointer]);
Runtime.removeFunction(pointer);
This way the C-code does not need to be aware of that it is transpiled to JS and any bridges required can purely be controlled from JS.
(code hacked into message composer; may contain errors)
There is a new way of achieving your requirement which is via embind.
Consider the following piece of C++ code.
#include <emscripten/bind.h>
using namespace emscripten;
void cbTest(emscripten::val cb)
{
cb();
}
EMSCRIPTEN_BINDINGS(my_module) {
function("cbTest", &cbTest);
}
The cbTest C++ function takes in a emscripten::val. This can be an object of any kind. For us this is a function object.
This is how you will call it from JS
var cbFunc = function() {
console.log("Hi, this is a cb");
}
Module.cbTest(cbFunc);
P.S This api is still under construction.
A thing that is frequently done in Emscripten is to map strong types to simple ones.
JS:
function callback(message) {
alert(message);
}
var func_map = {
0: callback
};
// C/C++ functions get a _ prefix added
function _invoke_callback(callback_id, text_ptr) {
func_map[callback_id](Pointer_stringify(text_ptr));
}
ccall("my_c_function", ..., 0);
C++:
// In C/C++ you only need to declare the func signature and
// make sure C is used to prevent name mangling
extern "C" void invoke_callback(int callback_id, const char* text);
void my_c_function(int callback_id) {
invoke_callback( callback_id, "Hello World!" );
}
And of course, you can add some glue code, so this gets very seamless.
I needed to write something very similar to what is described in the question. My code ended up looking like this:
C:
void call(void (*back)(char*)){
back("Hello!");
}
JS:
function back(text){
alert(Pointer_stringify(text));
}
var pointer = Runtime.addFunction(back);
var call = Module.cwrap('call', 'void', ['pointer']);
call(pointer);
Runtime.removeFunction(pointer);
Note that the pointer returned to the callback has to be dereferenced with Pointer_stringify.
You can find example code like this on GitHub.
Here's what I have gathered from several posts and by looking at Emscripten bundled code:
In C++:
#include <iostream>
#include <functional>
extern "C" {
void registerCallback(void(*back)(const char*));
void triggerCallback(char* message); // for invoking it from JS, just for this example
}
// global
std::function<void(const char*)> gCallback;
void registerCallback(void(*back)(const char*)){
gCallback = back;
}
void triggerCallback(char* message){
if (gCallback) {
gCallback(message);
} else {
std::cerr << "Cannot pass '"<< message <<"' to undefined callback\n";
}
}
An important thing, which was missing in other posts, is to compile C++ with RESERVED_FUNCTION_POINTERS=... flag, e.g.:
em++ -std=c++11 -s RESERVED_FUNCTION_POINTERS=20 source.cpp -s EXPORTED_FUNCTIONS="['_registerCallback','_triggerCallback']" -o try.html
After loading try.html into a browser, you can execute the following JS code in its console:
// Register a callback function
function callback(text){ alert("In JS: "+Pointer_stringify(text)); }
var cb = Runtime.addFunction(callback);
_registerCallback(cb);
// Invoke it with some "C string"
var jsStr = "XOXOXO";
var cStr = allocate(intArrayFromString(jsStr), 'i8', ALLOC_NORMAL)
_triggerCallback(cStr);
// Free Emscripten heap and release the function pointer
_free(cStr);
Runtime.removeFunction(cb);
You should see an alert with "In JS: XOXOXO".

Categories

Resources