typeSpec type

ahhhhhh this feels good.
types
Jordan Orelli 8 years ago
parent 8025667a58
commit 78b07284ca

@ -2,7 +2,6 @@ package ent
import (
"github.com/jordanorelli/hyperstone/bit"
"github.com/jordanorelli/hyperstone/dota"
)
var atom_types = map[string]typeFn{
@ -15,9 +14,8 @@ var atom_types = map[string]typeFn{
},
}
func atomType(flat *dota.ProtoFlattenedSerializerFieldT, env *Env) tÿpe {
var_type := env.symbol(int(flat.GetVarTypeSym()))
if t, ok := atom_types[var_type]; ok {
func atomType(spec *typeSpec, env *Env) tÿpe {
if t, ok := atom_types[spec.typeName]; ok {
Debug.Printf(" atom type")
return t
}

@ -12,7 +12,7 @@ type field struct {
func (f *field) fromProto(flat *dota.ProtoFlattenedSerializerFieldT, env *Env) error {
Debug.Printf("parse flat field: %s", prettyFlatField(flat, env))
t := parseType(flat, env)
t := parseFieldType(flat, env)
if t == nil {
return fmt.Errorf("unable to parse type %s", prettyFlatField(flat, env))
}

@ -4,7 +4,6 @@ import (
"math"
"github.com/jordanorelli/hyperstone/bit"
"github.com/jordanorelli/hyperstone/dota"
)
const (
@ -13,42 +12,38 @@ const (
f_center
)
func floatType(flat *dota.ProtoFlattenedSerializerFieldT, env *Env) tÿpe {
switch env.symbol(int(flat.GetVarTypeSym())) {
func floatType(spec *typeSpec, env *Env) tÿpe {
switch spec.typeName {
case "CNetworkedQuantizedFloat":
return qFloatType(flat, env)
return qFloatType(spec, env)
case "float32":
default:
return nil
}
if env.symbol(int(flat.GetVarEncoderSym())) == "coord" {
if spec.encoder == "coord" {
return nil
}
if env.symbol(int(flat.GetFieldSerializerNameSym())) == "simulationtime" {
if spec.serializer == "simulationtime" {
return nil
}
switch flat.GetBitCount() {
switch spec.bits {
case 0, 32:
Debug.Printf(" std float type")
return typeFn(float_t)
default:
return qFloatType(flat, env)
return qFloatType(spec, env)
}
}
func qFloatType(flat *dota.ProtoFlattenedSerializerFieldT, env *Env) tÿpe {
if flat.GetBitCount() < 0 {
func qFloatType(spec *typeSpec, env *Env) tÿpe {
if spec.bits < 0 {
return typeError("quantized float has invalid negative bit count specifier")
}
if flat.GetHighValue()-flat.GetLowValue() < 0 {
if spec.high-spec.low < 0 {
return typeError("quantized float has invalid negative range")
}
t := qfloat_t{
bits: uint(flat.GetBitCount()),
low: flat.GetLowValue(),
high: flat.GetHighValue(),
flags: int(flat.GetEncodeFlags()) & 0x7,
}
t := qfloat_t{typeSpec: *spec}
t.span = t.high - t.low
t.intervals = uint(1<<t.bits - 1)
t.interval = t.span / float32(t.intervals)
@ -72,10 +67,7 @@ func qFloatType(flat *dota.ProtoFlattenedSerializerFieldT, env *Env) tÿpe {
}
type qfloat_t struct {
bits uint
low float32
high float32
flags int
typeSpec
span float32 // total range of values
intervals uint // number of intervals in the quantization range
interval float32 // width of one interval

@ -2,15 +2,14 @@ package ent
import (
"github.com/jordanorelli/hyperstone/bit"
"github.com/jordanorelli/hyperstone/dota"
)
// a handle represents a soft pointer to an entity. handles are represented by
// IDs and can cross the client-server divide.
type handle int
func handleType(flat *dota.ProtoFlattenedSerializerFieldT, env *Env) tÿpe {
if env.symbol(int(flat.GetVarTypeSym())) != "CGameSceneNodeHandle" {
func handleType(spec *typeSpec, env *Env) tÿpe {
if spec.typeName != "CGameSceneNodeHandle" {
return nil
}

@ -2,11 +2,10 @@ package ent
import (
"github.com/jordanorelli/hyperstone/bit"
"github.com/jordanorelli/hyperstone/dota"
)
func hSeqType(flat *dota.ProtoFlattenedSerializerFieldT, env *Env) tÿpe {
if env.symbol(int(flat.GetVarTypeSym())) != "HSequence" {
func hSeqType(spec *typeSpec, env *Env) tÿpe {
if spec.typeName != "HSequence" {
return nil
}

@ -2,14 +2,13 @@ package ent
import (
"github.com/jordanorelli/hyperstone/bit"
"github.com/jordanorelli/hyperstone/dota"
)
func qAngleType(flat *dota.ProtoFlattenedSerializerFieldT, env *Env) tÿpe {
if env.symbol(int(flat.GetVarTypeSym())) != "QAngle" {
func qAngleType(spec *typeSpec, env *Env) tÿpe {
if spec.typeName != "QAngle" {
return nil
}
switch flat.GetBitCount() {
switch spec.bits {
case 0:
Debug.Printf(" qangle type")
return typeFn(func(r bit.Reader) (value, error) {

@ -15,12 +15,18 @@ type typeFn func(bit.Reader) (value, error)
func (fn typeFn) read(r bit.Reader) (value, error) { return fn(r) }
type typeParseFn func(*dota.ProtoFlattenedSerializerFieldT, *Env) tÿpe
type typeParseFn func(*typeSpec, *Env) tÿpe
func parseType(flat *dota.ProtoFlattenedSerializerFieldT, env *Env) tÿpe {
func parseFieldType(flat *dota.ProtoFlattenedSerializerFieldT, env *Env) tÿpe {
spec := new(typeSpec)
spec.fromProto(flat, env)
return parseTypeSpec(spec, env)
}
func parseTypeSpec(spec *typeSpec, env *Env) tÿpe {
coalesce := func(fns ...typeParseFn) tÿpe {
for _, fn := range fns {
if t := fn(flat, env); t != nil {
if t := fn(spec, env); t != nil {
return t
}
}
@ -43,3 +49,39 @@ 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))
}
type typeSpec struct {
name string
typeName string
bits uint
low float32
high float32
flags int
serializer string
serializerV int
send string
encoder string
}
func (s *typeSpec) fromProto(flat *dota.ProtoFlattenedSerializerFieldT, env *Env) {
s.name = env.symbol(int(flat.GetVarNameSym()))
s.typeName = env.symbol(int(flat.GetVarTypeSym()))
if flat.GetBitCount() < 0 {
// this would cause ridiculously long reads later if we let it overflow
panic("negative bit count: data is likely corrupt")
}
s.bits = uint(flat.GetBitCount())
s.low = flat.GetLowValue()
s.high = flat.GetHighValue()
s.flags = int(flat.GetEncodeFlags())
if flat.FieldSerializerNameSym != nil {
s.serializer = env.symbol(int(*flat.FieldSerializerNameSym))
}
s.serializerV = int(flat.GetFieldSerializerVersion())
if flat.SendNodeSym != nil {
s.send = env.symbol(int(*flat.SendNodeSym))
}
if flat.VarEncoderSym != nil {
s.encoder = env.symbol(int(*flat.VarEncoderSym))
}
}

Loading…
Cancel
Save