123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278 |
- package scope
- import (
- "container/list"
- "fmt"
- "fw/cp/node"
- "fw/cp/object"
- "fw/rt2/context"
- rt_mod "fw/rt2/module"
- "fw/utils"
- "math/rand"
- "reflect"
- "strconv"
- "ypk/assert"
- )
- func Id(of interface{}) (ret string) {
- assert.For(of != nil, 20)
- switch of.(type) {
- case object.Object:
- fmt.Println("id", of.(object.Object).Name(), reflect.TypeOf(of))
- //panic("fuck objects, use nodes")
- ret = of.(object.Object).Name()
- default:
- fmt.Println(reflect.TypeOf(of))
- panic("cannot identify")
- }
- assert.For(ret != "", 60)
- return ret
- }
- func This(i interface{}) Manager {
- assert.For(i != nil, 20)
- return i.(Manager)
- }
- func New() Manager {
- return new(manager).init()
- }
- type manager struct {
- d context.Domain
- areas *list.List
- opts struct {
- startFromArea *area
- }
- }
- type area struct {
- heap map[string]value
- cache map[string]object.Object
- root node.Node
- ready bool
- }
- type value interface {
- Set(x interface{})
- Get() interface{}
- }
- type direct struct {
- value
- data interface{}
- }
- type indirect struct {
- value
- ref object.Object
- mgr *manager
- area *area
- }
- // маскирует объект-параметр
- type mask struct {
- object.Object
- id int
- }
- func nextMask() int {
- return rand.Int()
- }
- type dummy struct{}
- var def *dummy = &dummy{}
- func (v *direct) Set(x interface{}) {
- assert.For(x != nil, 20)
- v.data = x
- utils.Println("set", x, reflect.TypeOf(x))
- }
- func (v *direct) Get() interface{} { return v.data }
- func (v *indirect) Set(x interface{}) {
- assert.For(x != nil, 20)
- assert.For(v.ref != nil, 21)
- v.mgr.Update(Id(v.ref), func(old interface{}) interface{} {
- return x
- })
- }
- func (v *indirect) Get() (ret interface{}) {
- assert.For(v.ref != nil, 20)
- _, ok := v.ref.(*mask)
- if !ok {
- v.mgr.opts.startFromArea = v.area
- }
- ret = v.mgr.Select(Id(v.ref))
- v.mgr.opts.startFromArea = nil
- return ret
- }
- func (m *manager) init() *manager {
- m.areas = list.New()
- return m
- }
- func (m *manager) Allocate(n node.Node, final bool) {
- mod := rt_mod.DomainModule(m.Domain())
- h := new(area)
- h.ready = final
- h.heap = make(map[string]value)
- h.cache = make(map[string]object.Object)
- h.root = n
- for _, o := range mod.Objects[n] {
- //fmt.Println(reflect.TypeOf(o))
- switch o.(type) {
- case object.VariableObject:
- switch o.(object.VariableObject).Type() {
- case object.COMPLEX:
- switch o.(object.VariableObject).Complex().(type) {
- case object.RecordType:
- for rec := o.(object.VariableObject).Complex().(object.RecordType); rec != nil; {
- for x := rec.Link(); x != nil; x = x.Link() {
- fmt.Println(o.Name(), ".", x.Name())
- }
- if rec.Base() != "" {
- rec = mod.TypeByName(n, rec.Base()).(object.RecordType)
- } else {
- rec = nil
- }
- }
- default:
- h.heap[Id(o)] = &direct{data: def}
- h.cache[Id(o)] = o
- }
- default:
- h.heap[Id(o)] = &direct{data: def}
- h.cache[Id(o)] = o
- }
- case object.ParameterObject:
- h.heap[Id(o)] = &indirect{mgr: m, area: h}
- h.cache[Id(o)] = o
- default:
- fmt.Println("wrong object type", reflect.TypeOf(o))
- }
- }
- m.areas.PushFront(h)
- fmt.Println("allocate", len(h.heap), "obj")
- }
- func (m *manager) set(a *area, o object.Object, val node.Node) {
- switch val.(type) {
- case node.ConstantNode:
- switch o.(type) {
- case object.VariableObject:
- m.Update(Id(o), func(old interface{}) interface{} {
- return val.(node.ConstantNode).Data()
- })
- case object.ParameterObject:
- assert.For(a.heap[Id(o)].(*indirect).ref == nil, 40)
- m := &mask{id: nextMask()}
- a.heap[Id(o)].(*indirect).ref = m
- a.heap[Id(m)] = &direct{data: val.(node.ConstantNode).Data()}
- default:
- panic("unknown value")
- }
- case node.VariableNode, node.ParameterNode:
- switch o.(type) {
- case object.VariableObject:
- m.Update(Id(o), func(old interface{}) interface{} {
- return m.Select(Id(val.Object()))
- })
- case object.ParameterObject:
- a.heap[Id(o)].(*indirect).ref = val.Object()
- fmt.Println(val.Object())
- }
- default:
- panic("unknown value")
- }
- }
- func (m *manager) Initialize(n node.Node, o object.Object, _val node.Node) {
- e := m.areas.Front()
- assert.For(e != nil, 20)
- h := e.Value.(*area)
- assert.For(h.root == n, 21)
- assert.For(!h.ready, 22)
- val := _val
- fmt.Println("initialize")
- for next := o; next != nil; next = next.Link() {
- assert.For(val != nil, 40)
- fmt.Println(reflect.TypeOf(next), next.Name(), ":", next.Type())
- fmt.Println(reflect.TypeOf(val))
- m.set(h, next, val)
- val = val.Link()
- }
- h.ready = true
- }
- func (m *manager) Dispose(n node.Node) {
- e := m.areas.Front()
- if e != nil {
- h := e.Value.(*area)
- assert.For(h.root == n, 21)
- m.areas.Remove(e)
- fmt.Println("dispose")
- }
- }
- func FindObjByName(mgr Manager, name string) (ret object.Object) {
- assert.For(name != "", 20)
- m := mgr.(*manager)
- for e := m.areas.Front(); (e != nil) && (ret == nil); e = e.Next() {
- h := e.Value.(*area)
- ret = h.cache[name]
- }
- return ret
- }
- func (m *manager) Select(id string) (ret interface{}) {
- assert.For(id != "", 20)
- for e := m.areas.Front(); (e != nil) && (ret == nil); e = e.Next() {
- h := e.Value.(*area)
- if (h != m.opts.startFromArea) && h.ready {
- ret = h.heap[id]
- }
- }
- assert.For(ret != nil, 40)
- ret = ret.(value).Get()
- if _, ok := ret.(*dummy); ok {
- ret = nil
- }
- return ret
- }
- func (m *manager) Update(id string, val ValueFor) {
- assert.For(id != "", 20)
- assert.For(val != nil, 21)
- var x *area
- for e := m.areas.Front(); (e != nil) && (x == nil); e = e.Next() {
- h := e.Value.(*area)
- if h.heap[id] != nil {
- x = h
- }
- }
- assert.For(x != nil, 40)
- old := x.heap[id].Get()
- if old == def {
- old = nil
- }
- tmp := val(old)
- assert.For(tmp != nil, 40) //если устанавливают значение NIL, значит делают что-то неверно
- x.heap[id].Set(tmp)
- }
- func (m *manager) Init(d context.Domain) {
- m.d = d
- }
- func (m *manager) Domain() context.Domain {
- return m.d
- }
- func (m *manager) Handle(msg interface{}) {}
- func (m *mask) Name() string { return strconv.Itoa(m.id) }
|