Open rhacking opened 6 years ago
Well, the way it's "supposed to work" is more like:
enum Buffer {
@:json({ target: 34963 }) ElementArrayBuffer(elementArrayBuffer:{ buffer:Int, byteOffset:Int, byteLength:Int });
@:json({ target: 34962 }) ArrayBuffer(arrayBuffer:{ buffer:Int, byteOffset:Int, byteLength:Int, byteStride:Int });
}
The point being that the byteStride
is actually only there if needed. But I'll look into making it possible this way ;)
Hmm, I can see why it would be better to do it like this (as indeed byteStride
is only there for ArrayBuffer
), but then you can't access, say, the buffer
property of an arbitrary buffer without first using a switch to extract it, even though any buffer will have this property.
Well, could solve that with abstracts or static extensions, but without really knowing the use case I can hardly give qualified advise ^^
That said, I will look into making this possible per @:json
. Right now you can do something like this:
//BufferTarget.hx
package whatever;
class BufferTargetParser {
public function new(_) {}
public function parse(value:Int):BufferTarget
return switch value {
case 34963: ElementArrayBuffer;
case 34962: ArrayBuffer;
default: throw 'Invalid buffer target $value';
}
}
@:jsonParse(whatever.BufferTarget.BufferTargetParser)//must be fully qualified name
enum BufferTarget {
@:json(34963) ElementArrayBuffer;
@:json(34962) ArrayBuffer;
}
Here are the tests for custom parsing and stringifying
Ah, I didn't know you could that. I solved it like this now:
typedef BufferViewRaw = {
var buffer : Int;
var byteLength : Int;
var byteOffset : Int;
var target : Int;
@:optional var byteStride : Int;
}
@:jsonParse(gltf.GLTFLoader.BufferViewParser)
typedef BufferView = {
var buffer : Int;
var byteLength : Int;
var byteOffset : Int;
var target : BufferTarget;
}
class BufferViewParser {
public function new(_) {}
public function parse(v:BufferViewRaw):BufferView {
return {
buffer: v.buffer,
byteLength: v.byteLength,
byteOffset: v.byteOffset,
target: switch v.target {
case 34963: ElementArrayBuffer;
case 34962: ArrayBuffer(v.byteStride == null ? Tight : Fixed(v.byteStride));
default: throw 'Invalid buffer target ${v.target}';
}
};
}
}
enum BufferTarget {
ElementArrayBuffer;
ArrayBuffer(stride : Stride);
}
It's a bit bulky this way, but I think the final type it gets makes more sense. Though the :json
modification would still be helpful for standalone enums that don't influence which other fields there are.
As far as I can see, there's no way of parsing
target
as an enum in the following example:The following results in
[haxe] invalid use of @:json
Right now I'm using an enum abstract, but I think it would be more elegant if something like the above were possible.