-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy patho.go
145 lines (118 loc) · 3.09 KB
/
o.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
package cpn
import (
"context"
"sync"
)
const (
// optionInitial means an initial place in the PN. Initial place doesn't have incoming edges
optionInitial uint64 = 1 << 0
// optionKeep means to don't clean up Strategy object in the terminal place. This is used for test purposes
optionKeep uint64 = 1 << 1
// optionLog means need to log an entity behaviour. Be careful, because this option makes syscalls what could change
// a scheduler behaviour
optionLog uint64 = 1 << 2
// optionTerminal means a terminal place in the PN. Terminal place doesn't have outgoing edges
optionTerminal uint64 = 1 << 3
)
const (
// stateClosed means place is closed, and it doesn't process tokens
stateClosed uint64 = 1 << 0
// stateProcessing means place is processing a token
stateProcessing uint64 = 1 << 1
// stateReady means place is ready to pass token forward
stateReady uint64 = 1 << 2
)
type state struct {
sync.RWMutex
v uint64
}
func (s *state) andnotor(andnot, or uint64) {
s.Lock()
defer s.Unlock()
s.v &= ^andnot
s.v |= or
}
func (s *state) andnot(v uint64) {
s.Lock()
defer s.Unlock()
s.v &= ^v
}
func (s *state) or(v uint64) {
s.Lock()
defer s.Unlock()
s.v |= v
}
func (s *state) state() uint64 {
s.RLock()
defer s.RUnlock()
return s.v
}
// PlaceOption is an abstraction to define place options
type PlaceOption interface {
Apply(*P)
}
// WithContext creates an option to use context
func WithContext(ctx context.Context) PlaceOption {
return contextOpt{ctx}
}
type contextOpt struct {
ctx context.Context
}
func (o contextOpt) Apply(p *P) {
p.ctx = o.ctx
}
// WithKeep creates an option to keep token in a terminal place
func WithKeep(keep bool) PlaceOption {
return keepOpt{keep}
}
type keepOpt struct {
keep bool
}
func (o keepOpt) Apply(p *P) {
if o.keep {
p.o |= optionKeep
return
}
p.o &= ^optionKeep
}
// WithStrategy creates an option to use specific strategy
func WithStrategy(s Strategy) PlaceOption {
return strategyOpt{s}
}
type strategyOpt struct {
strategy Strategy
}
func (o strategyOpt) Apply(p *P) {
p.strategy = o.strategy
}
// StrategyBuilder creates new strategy with required options
type StrategyBuilder func(opts ...StrategyOption) Strategy
// StrategyOption is an abstraction to define strategy option
type StrategyOption interface {
Apply(Strategy)
}
// WithStrategyBuilder returns an option to create strategy with required options
func WithStrategyBuilder(builder StrategyBuilder, opts ...StrategyOption) PlaceOption {
return strategyBuilderOpt{builder, opts}
}
type strategyBuilderOpt struct {
builder StrategyBuilder
opts []StrategyOption
}
func (o strategyBuilderOpt) Apply(p *P) {
p.strategy = o.builder(o.opts...)
}
// TransitionOption is an abstraction to define a transition option
type TransitionOption interface {
Apply(*T)
}
// WithTransformation return a transition option to use specified transformation
func WithTransformation(fn Transformation) TransitionOption {
return transformationOpt{fn}
}
type transformationOpt struct {
transformation Transformation
}
func (o transformationOpt) Apply(t *T) {
t.transformation = o.transformation
}