sf.go 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. package std
  2. import (
  3. "container/list"
  4. "fw/rt2/context"
  5. "fw/rt2/frame"
  6. "fw/rt2/scope"
  7. "fw/utils"
  8. "reflect"
  9. "ypk/assert"
  10. "ypk/halt"
  11. )
  12. type FlowFrame interface {
  13. }
  14. type RootFrame struct {
  15. inner list.List
  16. domain context.Domain
  17. queue []frame.Frame
  18. }
  19. func (f *RootFrame) init() *RootFrame {
  20. f.inner = *list.New()
  21. return f
  22. }
  23. func NewRoot() *RootFrame {
  24. return new(RootFrame).init()
  25. }
  26. func (r *RootFrame) Queue(f ...frame.Frame) (ret frame.Frame) {
  27. if len(f) == 0 {
  28. if len(r.queue) > 0 {
  29. ret = r.queue[0]
  30. old := r.queue
  31. r.queue = nil
  32. for i := 1; i < len(old); i++ {
  33. r.queue = append(r.queue, old[i])
  34. }
  35. }
  36. return ret
  37. } else {
  38. for i := range f {
  39. assert.For(f[i].Domain() != nil, 20)
  40. }
  41. r.queue = append(r.queue, f...)
  42. return nil
  43. }
  44. }
  45. func (f *RootFrame) PushFor(fr, parent frame.Frame) {
  46. _, ok := fr.(*RootFrame)
  47. if ok {
  48. panic("impossibru")
  49. }
  50. f.inner.PushFront(fr)
  51. if fr.Domain() == nil {
  52. if parent == nil {
  53. domain := f.Domain().(context.Factory).New()
  54. domain.Attach(context.SCOPE, scope.New(context.SCOPE))
  55. fr.Init(domain)
  56. } else {
  57. fr.Init(parent.Domain())
  58. }
  59. }
  60. fr.OnPush(f, parent)
  61. }
  62. func (f *RootFrame) Pop() {
  63. if f.inner.Front() != nil {
  64. elem := f.inner.Front()
  65. frame := elem.Value.(frame.Frame)
  66. frame.OnPop()
  67. f.inner.Remove(elem)
  68. } else {
  69. panic("it's empty stack")
  70. }
  71. }
  72. func (f *RootFrame) Top() (fr frame.Frame) {
  73. elem := f.inner.Front()
  74. if elem != nil {
  75. fr = elem.Value.(frame.Frame)
  76. }
  77. return fr
  78. }
  79. func (f *RootFrame) Drop() (fr frame.Frame) {
  80. elem := f.inner.Front()
  81. if elem != nil {
  82. fr = elem.Value.(frame.Frame)
  83. f.inner.Remove(elem)
  84. }
  85. return fr
  86. }
  87. func (f *RootFrame) Do() (res frame.WAIT) {
  88. var (
  89. trapped bool
  90. )
  91. if f.Top() != nil {
  92. x := f.Top()
  93. //цикл дейкстры
  94. for {
  95. wait := x.Do()
  96. //fmt.Println(wait)
  97. if wait == frame.LATER || wait == frame.BEGIN || wait == frame.END {
  98. break
  99. } else if wait == frame.NOW {
  100. } else if wait == frame.WRONG {
  101. trapped = true
  102. utils.PrintTrap("it's a trap")
  103. break
  104. //panic("something wrong") do nothing, it's a trap
  105. } else if wait == frame.STOP {
  106. if x == f.Top() {
  107. f.Pop()
  108. } else {
  109. halt.As(100, reflect.TypeOf(x), reflect.TypeOf(f.Top()), "do not stop if not top on stack")
  110. }
  111. break
  112. } else {
  113. panic("wrong wait code")
  114. }
  115. }
  116. }
  117. if f.Top() != nil && !trapped {
  118. res = frame.NOW
  119. } else {
  120. res = frame.STOP
  121. }
  122. return res
  123. }
  124. func (f *RootFrame) ForEach(run func(x frame.Frame) bool) {
  125. e := f.inner.Front()
  126. ok := true
  127. for (e != nil) && ok {
  128. if e.Value != nil {
  129. ok = run(e.Value.(frame.Frame))
  130. }
  131. e = e.Next()
  132. }
  133. }
  134. func (f *RootFrame) OnPush(a frame.Stack, b frame.Frame) {}
  135. func (f *RootFrame) OnPop() {}
  136. func (f *RootFrame) Parent() frame.Frame { return nil }
  137. func (f *RootFrame) Root() frame.Stack { return nil }
  138. func (f *RootFrame) Domain() context.Domain { return f.domain }
  139. func (f *RootFrame) Init(d context.Domain) {
  140. assert.For(f.domain == nil, 20)
  141. assert.For(d != nil, 21)
  142. f.domain = d
  143. }
  144. func (f *RootFrame) Handle(msg interface{}) {}