I'm playing with adding HTML5 CanvasObj bindings to the dom module, but I've encountered some javascript dynamic nastiness.
Here is a snippet of the bindings that I'm trying:
RenderingContext* {.importc.} = object of RootObj
fillStyle*: cstring
fillRect*: proc (x: int, y: int, width: int, height: int) {.nimcall.}
# blah blah more stuff
CanvasElement* = ref CanvasObj
CanvasObj {.importc.} = object of ElementObj
getContext*: proc (contextType: cstring): RenderingContext {.nimcall.}
# blah blah more stuff
Here's the problem. That fillStyle property in Javascript is actually not just a string. It can take three different types according to the documentation here:
https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/fillStyle
How do I handle this kind of variant-like binding? Thanks
You can try this:
proc `fillStyle=`(c: CanvasElement, value: MyType1 or MyType2 or MyType3) =
{.emit: "`c`.fillStyle = `value`;".}
Note that you may need a dedicated proc overload for a type that needs implicit converting. E.g. for cstring, because string literals will not convert to it.type
RenderingContext* {.importc.} = object of RootObj
fillRect*: proc (x: int, y: int, width: int, height: int) {.nimcall.}
proc `fillStyle=`*(c: RenderingContext, value: cstring) =
{.emit: """`c`.fillStyle = `value`;""".}
The {.emit: doesn't seem to be working, however. Here's how the generated js looks:
function fillstyleHEX3D_31125(c_31127, value_31128) {
var F={procname:"dom.fillStyle=",prev:framePtr,filename:"c:\\nim\\lib\\js\\dom.nim",line:0};
framePtr = F;
rawEcho(cstrToNimstr("haha"));
framePtr = framePtr.prev;
}
// blah blah ...
var canvas_32003 = document.getElementById("canvas");
if (!((canvas_32003 == null))) {
F.line = 6;
var ctx_32016 = canvas_32003.getContext("2d");
fillstyleHEX3D_31125(ctx_32016, "blue");
ctx_32016.fillRect(10, 10, 75, 50);
rawEcho(cstrToNimstr("haha"));
}
So it still synthesized some "fillstyle" function instead of emitting the literal string. Any ideas?
OK, {.emit: doesn't seem to be working at all for the js backend on 11.2. Then I found that support is pretty recent:
https://github.com/nim-lang/Nim/pull/3147
I'll check against master
True. Emit for js is pretty recent. Previously asm stmt was used for that stuff.
proc foo() =
asm """
alert("foo");
"""