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

Integer constants as enums #42

Open
rhacking opened this issue Feb 10, 2018 · 4 comments
Open

Integer constants as enums #42

rhacking opened this issue Feb 10, 2018 · 4 comments

Comments

@rhacking
Copy link

As far as I can see, there's no way of parsing target as an enum in the following example:

    "bufferViews": [
        {
            "buffer": 0,
            "byteOffset": 576,
            "byteLength": 72,
            "target": 34963
        },
        {
            "buffer": 0,
            "byteOffset": 0,
            "byteLength": 576,
            "byteStride": 12,
            "target": 34962
        }
    ],

The following results in [haxe] invalid use of @:json

enum BufferTarget {
    @:json(34963) ElementArrayBuffer;
    @:json(34962) ArrayBuffer;
}

Right now I'm using an enum abstract, but I think it would be more elegant if something like the above were possible.

@back2dos
Copy link
Member

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 ;)

@rhacking
Copy link
Author

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.

@back2dos
Copy link
Member

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

@rhacking
Copy link
Author

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants