two types now
parent
f1c4db00fb
commit
17dd5d399a
@ -0,0 +1,67 @@
|
||||
package ent
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/jordanorelli/hyperstone/bit"
|
||||
"github.com/jordanorelli/hyperstone/dota"
|
||||
)
|
||||
|
||||
const (
|
||||
f_min = 1 << iota
|
||||
f_max
|
||||
f_center
|
||||
)
|
||||
|
||||
func qFloatType(flat *dota.ProtoFlattenedSerializerFieldT, env *Env) tÿpe {
|
||||
if env.symbol(int(flat.GetVarTypeSym())) != "CNetworkedQuantizedFloat" {
|
||||
return nil
|
||||
}
|
||||
if flat.GetBitCount() < 0 {
|
||||
return typeError("quantized float has invalid negative bit count specifier")
|
||||
}
|
||||
if flat.GetHighValue()-flat.GetLowValue() < 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.span = t.high - t.low
|
||||
t.intervals = uint(1<<t.bits - 1)
|
||||
t.interval = t.span / float32(t.intervals)
|
||||
|
||||
if t.flags > 0 {
|
||||
t.special = new(float32)
|
||||
}
|
||||
|
||||
switch {
|
||||
case t.flags&f_min > 0:
|
||||
*t.special = t.low
|
||||
case t.flags&f_max > 0:
|
||||
*t.special = t.high
|
||||
case t.flags&f_center > 0:
|
||||
*t.special = t.low + (t.high+t.low)*0.5
|
||||
}
|
||||
return t
|
||||
}
|
||||
|
||||
type qfloat_t struct {
|
||||
bits uint
|
||||
low float32
|
||||
high float32
|
||||
flags int
|
||||
span float32 // total range of values
|
||||
intervals uint // number of intervals in the quantization range
|
||||
interval float32 // width of one interval
|
||||
special *float32
|
||||
}
|
||||
|
||||
func (t qfloat_t) read(r bit.Reader) (value, error) {
|
||||
if t.special != nil && bit.ReadBool(r) {
|
||||
return *t.special, nil
|
||||
}
|
||||
return nil, fmt.Errorf("I'll get there")
|
||||
}
|
@ -1,6 +1,40 @@
|
||||
package ent
|
||||
|
||||
type tÿpe struct {
|
||||
name string
|
||||
alloc func(...interface{}) value
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/jordanorelli/hyperstone/bit"
|
||||
"github.com/jordanorelli/hyperstone/dota"
|
||||
)
|
||||
|
||||
type tÿpe interface {
|
||||
read(bit.Reader) (value, error)
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
func parseType(flat *dota.ProtoFlattenedSerializerFieldT, env *Env) tÿpe {
|
||||
coalesce := func(fns ...typeParseFn) tÿpe {
|
||||
for _, fn := range fns {
|
||||
if t := fn(flat, env); t != nil {
|
||||
return t
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
return coalesce(atomType, qFloatType)
|
||||
}
|
||||
|
||||
// a type error is both an error and a type. It represents a type that we were
|
||||
// unable to correctly parse. It can be interpreted as an error or as a type;
|
||||
// when interpreted as a type, it errors every time it tries to read a value.
|
||||
type typeError string
|
||||
|
||||
func (e typeError) Error() string { return string(e) }
|
||||
func (e typeError) read(r bit.Reader) (value, error) {
|
||||
return nil, fmt.Errorf("type error: %s", string(e))
|
||||
}
|
||||
|
@ -1,9 +1,3 @@
|
||||
package ent
|
||||
|
||||
import (
|
||||
"github.com/jordanorelli/hyperstone/bit"
|
||||
)
|
||||
|
||||
type value interface {
|
||||
read(bit.Reader) error
|
||||
}
|
||||
type value interface{}
|
||||
|
Loading…
Reference in New Issue