Hi,
I need to define some tricky data structure and got stuck with defining generic parameter in an abstract enum.
I think the best to show the concrete case, I hope you will get my point from the example:
https://try.haxe.org/#Ac1D1
Hi,
I need to define some tricky data structure and got stuck with defining generic parameter in an abstract enum.
I think the best to show the concrete case, I hope you will get my point from the example:
https://try.haxe.org/#Ac1D1
I think the easy (but discouraged) answer is:
typedef MY_GENERIC_DATA=Dynamic
The other answer is, “don’t use generic structures.” In other words, specify all of the possible structures and use them accordingly.
I think you may need a macro to do this, since I don’t believe Haxe supports String->T->Void
(etc) right now
Assuming that you’re aiming at proper type-checking of your extern class methods, maybe following will be a feasible solution (https://try.haxe.org/#c5798):
class Test {
static function main() {
var dispatcher = new EventDispatcher();
// assuming `name: String` is an event name
dispatcher.on(MyEvent.SomeEvent, function(name:String, data:MyData): Void {
trace(name);
trace(data.id);
trace(data.name);
});
dispatcher.on(MyEvent.OtherEvent, function(name:String, data:Int): Void {
trace(name);
trace(data);
});
// dispatcher.on(MyEvent.SomeEvent, function(name:String, data:Int): Void { // compilation error - as expected
// trace(name);
// });
// not sure if this is how it's meant to be used with your extern but that's what I figured out from your sample code
dispatcher.dispatch(MyEvent.SomeEvent, {id: "someId", name: "someName"});
dispatcher.dispatch(MyEvent.OtherEvent, 13);
// dispatcher.dispatch(MyEvent.OtherEvent, {id: "someId", name: "someName"}); // compilation error - as expected
}
}
// NOTE: can't use extern since 'Type required for extern classes and interfaces' - can't use type parameters
// NOTE: could be also an `abstract` (probably :))
// NOTE: could simply use static methods if JS implementation uses plain functions
class EventDispatcher {
private var ext: Dynamic;
public function new() {
// here you have to write native, i.e. JS, implementation creating actual "extern" class instance
ext = new NativeEventDispatcher();
}
public function on<Data, Callback: haxe.Constraints.Function>(event:MyEvent<Data, Callback>, listener:Callback) {
// here you have to write native, i.e. JS, implementation calling actual "extern" `on` method
ext.on(event, listener);
}
public function dispatch<Data, Callback: haxe.Constraints.Function>(event:MyEvent<Data, Callback>, data:Data) {
// here you have to write native, i.e. JS, implementation calling actual "extern" `dispatch` method
ext.dispatch(event, data);
}
}
// NOTE: couldn't make `EventDispatcher` work with `String->Data->Void` but `haxe.Constraints.Function` is enough for proper type-checking of `EventDispatcher` methods
// NOTE: had to change `OtherEvent` to an uniform callback definition, i.e. `String->Int->Void`
@:enum abstract MyEvent<Data, Callback: haxe.Constraints.Function>(String) {
var SomeEvent:MyEvent<MyData, String->MyData->Void> = "someEvent";
var OtherEvent:MyEvent<Int, String->Int->Void> = "otherEvent";
}
typedef MyData = {
var id:String;
var name:String;
}
// NOTE: example "native" implementation
@:keep // without this DCE removes this class implementation - it's an example, so whatever
class NativeEventDispatcher {
private var listeners = new Map<String, Dynamic>();
public function new() {}
public function on(event:Dynamic, listener:Dynamic) {
// only single listener for brevity
listeners.set(event, listener);
}
public function dispatch(event:Dynamic, data:Dynamic) {
// no error-logic for brevity
listeners.get(event)(event, data);
}
}
Edit.
Actually you can have var OtherEvent:MyEvent<Int, Int->Void> = "otherEvent";
if your extern invokes callback functions with different arguments for specific event types. See Try Haxe !.
Are you trying to implement an EventEmitter ? I did something here GitHub - darmie/EventEmitter: Cross-Platform Minimal EventEmitter library implemented in Haxe. , you may want to take a look and improve upon it?
© 2018-2020 Haxe Foundation - Powered by Discourse