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

[js] @:expose enum to js #4630

Open
azrafe7 opened this issue Nov 7, 2015 · 15 comments
Open

[js] @:expose enum to js #4630

azrafe7 opened this issue Nov 7, 2015 · 15 comments
Labels
Milestone

Comments

@azrafe7
Copy link
Contributor

azrafe7 commented Nov 7, 2015

I can't find a way to expose an enum to js, and I see that recently someone else posted on gitter with the same problem.

I'm currently using a hackish solution to achieve it (see this discussion on the mailing list), but I'm wondering if there's a standard way to do it or if it has been intentionally left out.

@andyli andyli added the platform-javascript Everything related to JS / JavaScript label Nov 8, 2015
@Simn
Copy link
Member

Simn commented Nov 8, 2015

The run-time representation of enums is not defined in Haxe, so exposing them doesn't make a whole lot of sense. You can work with the current representation and extract information that way, but this is not guaranteed to be stable.

Either way, this is not really a Haxe issue. Feel free to discuss this on the haxelang google group.

@Simn Simn closed this as completed Nov 8, 2015
@ncannasse
Copy link
Member

If you don't have any parameter, you can use abstract enums for that.

@azrafe7
Copy link
Contributor Author

azrafe7 commented Nov 10, 2015

@ncannasse, but using an abstract enum will inline the values, forcing the user to hardcode them on the js side, no?

@ncannasse
Copy link
Member

@azrafe7 that shouldn't be a problem as long as they are ==, actually an enum with no parameter is guaranteed to be == to the same value.

@azrafe7
Copy link
Contributor Author

azrafe7 commented Nov 11, 2015

What I meant to say is that when exposing an abstract enum the values are not wrapped in an enum/object, so from the js side the user must know in advance what the possible values could be, without any way to discover them (apart from the docs of the original hx, if any).

@Justinfront
Copy link
Contributor

To support Javascripter users specifically, you would need to define the values as a static values and turn off full DCE so that they are retained in the code.

http://try.haxe.org/#Eb854

You can see in the JS output that the statics are retained, selectively copying aspects of the output code you can see that a js user could create meaningful tests using the library while internally the code using Trio could be optimised:

TrioJS.Good = 7;
TrioJS.Bad = 666;
TrioJS.Ugly = 300;
Test.main = function() {
    var actor = 7;
    console.log("Actor is Good is " + Std.string(actor == TrioJS.Good));
};

I don't know if this is a really good approach or how Haxe compile could be adapted to support this. Perhaps it would be note added to documentation if it's a sensible approach, it seems viable but without real case it's difficult to be sure, but seems rather extreme to get the js generator to automatically generate a TrioJS class, and certainly it would probably never be used if a compiler option was added just for this. Tricky question. Abstract Enums are not intended for use by Javascript users so it's not surprising that they have no specific js support. But suggested the work round in case it's useful.

@Justinfront
Copy link
Contributor

( You may wonder why 300 is ugly http://www.geeksforgeeks.org/ugly-numbers/ )

@Justinfront
Copy link
Contributor

Azarfe7, ofcourse this does not help with complex enums used in hxDeadalus but I am not sure that they would need to be accessed by the JS user directly, not looked at what gets outputted for them, if the topic was related to the js focused version that someone was optimising for js target.

@azrafe7
Copy link
Contributor Author

azrafe7 commented Nov 12, 2015

@Justinfront, this is not related to hxDaedalus. Sure one could go with manually wrapping the enum with a static class on the haxe side and expose that, but it's somewhat counter intuitive (adding @:expose automatically works with classes/functions/etc., but not with enums). Also that requires additional work (f.e. think of a Key enum that exhaustively lists/maps chars to keycodes). Furthermore, adding the expose meta to the enum doesn't warn about it not being exported (in the case of a standard enum). And in the case of an abstract one, the class gets exported, but as an empty object! (the actual values being obviously only compile-time ones).

Yeah, I figured out pattern matching is a problem when transpiling, but maybe something can be done to solve this kind of issues when simple/no-parameters enums are involved.

Now please don't hate me @Simn and @ncannasse ;). Let's discuss it more.

@filt3rek
Copy link
Contributor

Hej all !
So there is still no way to expose a Haxe enum to JS please ?

@kevinresol
Copy link
Contributor

The use case may not necessarily be inspecting the enum value content. It could be an API function accepting an enum. Enum constructors are just static constants or functions I think it is ok to expose them.

@filt3rek
Copy link
Contributor

I think it would be very interesting to have it implemented on JS, if it's not much work, just in order to have something consistent on Haxe targets, even if there are many other ways to achieve what we want without using enums.
What do you think about that please ?

@kevinresol
Copy link
Contributor

Can we reopen this?

As I said, the use case is not to inspect the enum value but provide a way for JS (non-haxe) users to create Haxe enum which can be passed to Haxe-generated APIs.

@nadako
Copy link
Member

nadako commented Mar 26, 2019

Makes sense to me

@vantreeseba
Copy link

vantreeseba commented Mar 28, 2021

I don't know if this is useful, but generally this is how I go about exposing enums for use in js.

The idea being that the API "looks" the same, but since it's the static class that is exposed, with the values there, it can be exported and anything it generates can be used an any exposed API functions that use the inner abstract enum.

package dropecho.behavior_tree.node;

#if js
@:enum
@:expose("bt.NODE_STATUS")
class NODE_STATUS_IMPL {
  static public var SUCCESS = 0;
  static public var FAILURE = 1;
  static public var RUNNING = 2;
}

@:enum
abstract NODE_STATUS(Int) {
  var SUCCESS = 0;
  var FAILURE = 1;
  var RUNNING = 2;
}

#else
@:enum
@:expose("bt.NODE_STATUS")
abstract NODE_STATUS(Int) {
	var SUCCESS = 0;
	var FAILURE = 1;
	var RUNNING = 2;
}

#end

@Simn Simn removed this from the Release 4.3 milestone Mar 24, 2023
@Simn Simn added this to the Later milestone Mar 24, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

10 participants