Closed hontvari closed 2 days ago
Sure, just forgot to mention this in documentation. You are right, if you want to bind JS constructor, then supply (empty) constructor in Java class (actually, you can add whatever code you want, TeaVM will just ignore it). You can examine existing API declarations like RegExp. Also note that if you want to map non-abstract Java class to JS class, you must annotate it with @JSClass
annotation.
It's also possible to represent constructors via static method. In this case you can use @JSBody
declaration. Historically, this was the only way to map constructors, but then direct constructor mapping was added.
Added documentation here: https://teavm.org/docs/runtime/jso.html (see 'Mapping constructors' section, you may need to clean cache).
Thank you, the documentation addition is understandable, as well as your comment above.
A new question is appeared in the meantime, but that may be a different issue and not related to htis: what about those "constructor" functions which return an object. Something like in case of stats.js: https://github.com/mrdoob/stats.js/blob/master/src/Stats.js
I tried to declare a constructor but TeaVM issued an error message (during the build?). I solved the case by writing a static create function with @JSBody "return new Stats()". Is that the correct way or is there a way with Java constructor declaration?
What build-time error did you get?
As for "function which returns an object". From TeaVM's prospective it's an implementation detail. The only different between "constructors" and "functions" is that when calling former, TeaVM adds 'new' keyword before them. From your example I see that it's ok to just call Stats()
, so it's not necessary to map it as a constructor.
What build-time error did you get?
I cannot reproduce. I declared a constructor and it just works.
@JSClass
public class Stats implements JSObject {
public Stats() {}
// @JSBody(script = "return new Stats();")
// static Stats create() { throw new RuntimeException(); }
//public Stats() {}
public native void showPanel( int panelNo );
public native Panel addPanel(Panel panel);
public native void begin();
public native void end();
@JSProperty
public native HTMLElement getDom();
public interface Panel extends JSObject {
@JSBody(params = { "name", "fg", "bg" }, script = "return new Stats.Panel(name, fg, bg);")
static Panel create(String name, String fg, String bg) { throw new RuntimeException(); }
void update(double value, double maxValue);
@JSProperty
HTMLElement getDom();
}
}
...
fpsStats = new Stats();
fpsStatsUpdatePanel = fpsStats.addPanel(Stats.Panel.create(
"up-µs", "#ff8", "#221"));
As for "function which returns an object". From TeaVM's prospective it's an implementation detail. The only different between "constructors" and "functions" is that when calling former, TeaVM adds 'new' keyword before them. From your example I see that it's ok to just call
Stats()
, so it's not necessary to map it as a constructor.
So I can declare an overlay function like this(but now that the constructor works this is unnecessary)? @JSBody(script="Stats()") Stats create() {}
Thank you!
As far as I see, constructors should be implemented by providing a usual Java constructor but with empty body. Could you please confirm this and mention in the documentation?
ChatGPT hallucinates an annotation for this, which does not exists, or recommends static create methods, which seems to be false, or at least unrelated.