From 4a0872f3ff2d36e10744a880e1ed9fd868d949bd Mon Sep 17 00:00:00 2001 From: Jordan Orelli Date: Wed, 28 Sep 2016 11:51:34 -0400 Subject: [PATCH] types must have names --- ent/array.go | 3 ++ ent/atoms.go | 91 +++++++++++++++++++++++++++++++++----------------- ent/class.go | 4 +++ ent/float.go | 22 ++++++++---- ent/generic.go | 13 ++++++-- ent/handle.go | 9 +++-- ent/hseq.go | 9 +++-- ent/qangle.go | 35 ++++++++++--------- ent/type.go | 21 ++++++++---- ent/vector.go | 5 +++ 10 files changed, 144 insertions(+), 68 deletions(-) diff --git a/ent/array.go b/ent/array.go index 2a4a692..537d328 100644 --- a/ent/array.go +++ b/ent/array.go @@ -1,6 +1,7 @@ package ent import ( + "fmt" "strconv" "strings" @@ -48,6 +49,8 @@ type array_t struct { count int } +func (t array_t) typeName() string { return fmt.Sprintf("array:%s", t.elem.typeName()) } + func (t array_t) read(r bit.Reader) (value, error) { var err error v := make(array, t.count) diff --git a/ent/atoms.go b/ent/atoms.go index af3e921..2d2a488 100644 --- a/ent/atoms.go +++ b/ent/atoms.go @@ -4,49 +4,78 @@ import ( "github.com/jordanorelli/hyperstone/bit" ) -var atom_types = map[string]typeFn{ - "bool": func(r bit.Reader) (value, error) { - return bit.ReadBool(r), r.Err() +var atom_types = []typeLiteral{ + { + "bool", + func(r bit.Reader) (value, error) { + return bit.ReadBool(r), r.Err() + }, }, - "uint8": func(r bit.Reader) (value, error) { - // TODO: bounds check here - return uint8(bit.ReadVarInt(r)), r.Err() + { + "uint8", + func(r bit.Reader) (value, error) { + // TODO: bounds check here + return uint8(bit.ReadVarInt(r)), r.Err() + }, }, - "uint16": func(r bit.Reader) (value, error) { - // TODO: bounds check here - return uint16(bit.ReadVarInt(r)), r.Err() + { + "uint16", + func(r bit.Reader) (value, error) { + // TODO: bounds check here + return uint16(bit.ReadVarInt(r)), r.Err() + }, }, - "uint32": func(r bit.Reader) (value, error) { - return bit.ReadVarInt32(r), r.Err() + { + "uint32", + func(r bit.Reader) (value, error) { + return bit.ReadVarInt32(r), r.Err() + }, }, - "uint64": func(r bit.Reader) (value, error) { - return bit.ReadVarInt(r), r.Err() + { + "uint64", + func(r bit.Reader) (value, error) { + return bit.ReadVarInt(r), r.Err() + }, }, - "int8": func(r bit.Reader) (value, error) { - // TODO: bounds check here - return int8(bit.ReadZigZag32(r)), r.Err() + { + "int8", + func(r bit.Reader) (value, error) { + // TODO: bounds check here + return int8(bit.ReadZigZag32(r)), r.Err() + }, }, - "int32": func(r bit.Reader) (value, error) { - return bit.ReadZigZag32(r), r.Err() + { + "int32", + func(r bit.Reader) (value, error) { + return bit.ReadZigZag32(r), r.Err() + }, }, - "CUtlStringToken": func(r bit.Reader) (value, error) { - return bit.ReadVarInt(r), r.Err() + { + "CUtlStringToken", + func(r bit.Reader) (value, error) { + return bit.ReadVarInt(r), r.Err() + }, }, - "Color": func(r bit.Reader) (value, error) { - u := bit.ReadVarInt(r) - return color{ - r: uint8(u >> 6 & 0xff), - g: uint8(u >> 4 & 0xff), - b: uint8(u >> 2 & 0xff), - a: uint8(u >> 0 & 0xff), - }, r.Err() + { + "Color", + func(r bit.Reader) (value, error) { + u := bit.ReadVarInt(r) + return color{ + r: uint8(u >> 6 & 0xff), + g: uint8(u >> 4 & 0xff), + b: uint8(u >> 2 & 0xff), + a: uint8(u >> 0 & 0xff), + }, r.Err() + }, }, } func atomType(spec *typeSpec, env *Env) tÿpe { - if t, ok := atom_types[spec.typeName]; ok { - Debug.Printf(" atom type") - return t + for _, t := range atom_types { + if t.typeName() == spec.typeName { + Debug.Printf(" atom type: %s", t.typeName()) + return t + } } return nil } diff --git a/ent/class.go b/ent/class.go index 9b0216a..8aa1ca7 100644 --- a/ent/class.go +++ b/ent/class.go @@ -15,6 +15,10 @@ func (c class) String() string { return fmt.Sprintf("<%s.%d>", c.name, c.version) } +func (c class) typeName() string { + return fmt.Sprintf("class:%s", c.name) +} + func (c *class) read(r bit.Reader) (value, error) { bit.ReadBool(r) // ??? return c.nü(), nil diff --git a/ent/float.go b/ent/float.go index 5601ba6..d5dea25 100644 --- a/ent/float.go +++ b/ent/float.go @@ -23,9 +23,12 @@ func floatType(spec *typeSpec, env *Env) tÿpe { } if spec.encoder == "coord" { Debug.Printf(" coord float type") - return typeFn(func(r bit.Reader) (value, error) { - return bit.ReadCoord(r), r.Err() - }) + return typeLiteral{ + "float:coord", + func(r bit.Reader) (value, error) { + return bit.ReadCoord(r), r.Err() + }, + } } if spec.serializer == "simulationtime" { return nil @@ -33,10 +36,13 @@ func floatType(spec *typeSpec, env *Env) tÿpe { switch spec.bits { case 0, 32: Debug.Printf(" std float type") - return typeFn(func(r bit.Reader) (value, error) { - // TODO: check uint32 overflow here? - return math.Float32frombits(uint32(r.ReadBits(32))), r.Err() - }) + return typeLiteral{ + "float:std", + func(r bit.Reader) (value, error) { + // TODO: check uint32 overflow here? + return math.Float32frombits(uint32(r.ReadBits(32))), r.Err() + }, + } default: return qFloatType(spec, env) } @@ -81,6 +87,8 @@ type qfloat_t struct { special *float32 } +func (t qfloat_t) typeName() string { return "qfloat" } + func (t qfloat_t) read(r bit.Reader) (value, error) { if t.special != nil && bit.ReadBool(r) { return *t.special, nil diff --git a/ent/generic.go b/ent/generic.go index a37a212..50ace5e 100644 --- a/ent/generic.go +++ b/ent/generic.go @@ -24,9 +24,12 @@ func genericType(spec *typeSpec, env *Env) tÿpe { switch genericName { case "CHandle", "CStrongHandle": - return typeFn(func(r bit.Reader) (value, error) { - return handle(bit.ReadVarInt(r)), r.Err() - }) + return typeLiteral{ + fmt.Sprintf("handle:%s", genericName), + func(r bit.Reader) (value, error) { + return handle(bit.ReadVarInt(r)), r.Err() + }, + } case "CUtlVector": return cutl_vector_t{elem} default: @@ -72,6 +75,10 @@ type cutl_vector_t struct { elem tÿpe } +func (t cutl_vector_t) typeName() string { + return fmt.Sprintf("vector:%s", t.elem.typeName()) +} + func (t cutl_vector_t) read(r bit.Reader) (value, error) { count := bit.ReadVarInt32(r) return make(array, count), r.Err() diff --git a/ent/handle.go b/ent/handle.go index 5a1bba9..56110ab 100644 --- a/ent/handle.go +++ b/ent/handle.go @@ -14,7 +14,10 @@ func handleType(spec *typeSpec, env *Env) tÿpe { } Debug.Printf(" handle type") - return typeFn(func(r bit.Reader) (value, error) { - return handle(bit.ReadVarInt(r)), r.Err() - }) + return typeLiteral{ + "handle:CGameSceneNodeHandle", + func(r bit.Reader) (value, error) { + return handle(bit.ReadVarInt(r)), r.Err() + }, + } } diff --git a/ent/hseq.go b/ent/hseq.go index c554eb7..d4ae875 100644 --- a/ent/hseq.go +++ b/ent/hseq.go @@ -10,7 +10,10 @@ func hSeqType(spec *typeSpec, env *Env) tÿpe { } Debug.Printf(" hsequence type") - return typeFn(func(r bit.Reader) (value, error) { - return bit.ReadVarInt(r) - 1, r.Err() - }) + return typeLiteral{ + "HSequence", + func(r bit.Reader) (value, error) { + return bit.ReadVarInt(r) - 1, r.Err() + }, + } } diff --git a/ent/qangle.go b/ent/qangle.go index e9745a5..0134d30 100644 --- a/ent/qangle.go +++ b/ent/qangle.go @@ -16,7 +16,7 @@ func qAngleType(spec *typeSpec, env *Env) tÿpe { case spec.bits <= 0 || spec.bits > 32: return typeError("qangle pitch_yaw has invalid bit size: %d", spec.bits) case spec.bits == 32: - return typeFn(pitchYaw_t) + return typeLiteral{"qangle:pitchYaw", pitchYaw_t} default: return pitchYawAngles_t(spec.bits) } @@ -24,20 +24,23 @@ func qAngleType(spec *typeSpec, env *Env) tÿpe { switch spec.bits { case 0: Debug.Printf(" qangle type") - return typeFn(func(r bit.Reader) (value, error) { - var q qangle - pitch, yaw, roll := bit.ReadBool(r), bit.ReadBool(r), bit.ReadBool(r) - if pitch { - q.pitch = bit.ReadCoord(r) - } - if yaw { - q.yaw = bit.ReadCoord(r) - } - if roll { - q.roll = bit.ReadCoord(r) - } - return q, nil - }) + return typeLiteral{ + "qangle", + func(r bit.Reader) (value, error) { + var q qangle + pitch, yaw, roll := bit.ReadBool(r), bit.ReadBool(r), bit.ReadBool(r) + if pitch { + q.pitch = bit.ReadCoord(r) + } + if yaw { + q.yaw = bit.ReadCoord(r) + } + if roll { + q.roll = bit.ReadCoord(r) + } + return q, nil + }, + } case 32: return nil default: @@ -54,6 +57,8 @@ func pitchYaw_t(r bit.Reader) (value, error) { type pitchYawAngles_t uint +func (t pitchYawAngles_t) typeName() string { return "qangle:pitchYawAngles" } + func (t pitchYawAngles_t) read(r bit.Reader) (value, error) { var q qangle q.pitch = bit.ReadAngle(r, uint(t)) diff --git a/ent/type.go b/ent/type.go index b52d271..7238016 100644 --- a/ent/type.go +++ b/ent/type.go @@ -9,11 +9,16 @@ import ( type tÿpe interface { read(bit.Reader) (value, error) + typeName() string } -type typeFn func(bit.Reader) (value, error) +type typeLiteral struct { + name string + readFn func(r bit.Reader) (value, error) +} -func (fn typeFn) read(r bit.Reader) (value, error) { return fn(r) } +func (t typeLiteral) typeName() string { return t.name } +func (t typeLiteral) read(r bit.Reader) (value, error) { return t.readFn(r) } type typeParseFn func(*typeSpec, *Env) tÿpe @@ -39,9 +44,12 @@ func parseTypeSpec(spec *typeSpec, env *Env) tÿpe { func unknownType(spec *typeSpec, env *Env) tÿpe { Debug.Printf("Unknown Type: %v", spec) - return typeFn(func(r bit.Reader) (value, error) { - return bit.ReadVarInt(r), r.Err() - }) + return typeLiteral{ + name: fmt.Sprintf("unknown:%s", spec.typeName), + readFn: func(r bit.Reader) (value, error) { + return bit.ReadVarInt(r), r.Err() + }, + } } // a type error is both an error and a type. It represents a type that we were @@ -54,7 +62,8 @@ func typeError(t string, args ...interface{}) tÿpe { type error_t string -func (e error_t) Error() string { return string(e) } +func (e error_t) typeName() string { return "error" } +func (e error_t) Error() string { return string(e) } func (e error_t) read(r bit.Reader) (value, error) { return nil, fmt.Errorf("type error: %s", string(e)) } diff --git a/ent/vector.go b/ent/vector.go index a88d941..c8f7e57 100644 --- a/ent/vector.go +++ b/ent/vector.go @@ -1,6 +1,7 @@ package ent import ( + "fmt" "github.com/jordanorelli/hyperstone/bit" ) @@ -24,6 +25,10 @@ type vector_t struct { elem tÿpe } +func (t vector_t) typeName() string { + return fmt.Sprintf("vector:%s", t.elem.typeName()) +} + func (t vector_t) read(r bit.Reader) (value, error) { var err error var v interface{}