-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathObservable.ms
151 lines (134 loc) · 3.33 KB
/
Observable.ms
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
146
147
148
149
150
151
/*! © 2022 imaoki | MIT License | https://github.com/imaoki */
/*-
通知を発行する仕組みを提供する。
@remarks 通知を受け取る関数は次のように実装する。
```maxscript
fn update type param = (
case type of (
(#Foo): ()
(#Bar): ()
default: ()
)
ok
)
```
| 引数 | 内容 |
| ------- | ---------- |
| `type` | 通知名 |
| `param` | 通知データ |
*/
struct ObservableStruct (
/*- @prop <Array[<MAXScriptFunction>]> */
private observers = #(),
/*
public fn Count = (),
public fn HasSubscribed obj = (),
public fn Notify type param = (),
public fn Subscribe obj = (),
public fn Unsubscribe obj = (),
private fn findObserver obj = (),
private fn isValidObserver obj = (),
*/
/*-
登録されているオブザーバの数を取得する。
@returns <Integer>
*/
public fn Count = (
this.observers.Count
),
/*-
オブザーバが登録済みかどうかを判定する。
@param obj <MAXScriptFunction>
@returns <BooleanClass>
*/
public fn HasSubscribed obj = (
this.findObserver obj > 0
),
/*-
通知を発行する。
@param type <Name> 通知名。
@param param <Any> 通知データ。
@returns <OkClass>
*/
public fn Notify type param = (
for observer in this.observers do (
observer type param
)
ok
),
/*-
通知元として購読する。
@param obj <MAXScriptFunction>
@returns <BooleanClass> オブザーバが存在する場合は`true`、失敗した場合は`false`。
*/
public fn Subscribe obj = (
if this.findObserver obj == 0 do (
append this.observers obj
)
this.findObserver obj > 0
),
/*-
購読を解除する。
@param obj <MAXScriptFunction>
@returns <BooleanClass> 成功した場合は`true`、失敗した場合は`false`。
*/
public fn Unsubscribe obj = (
local index = this.findObserver obj
if index > 0 do (
deleteItem this.observers index
)
this.findObserver obj <= 0
),
/*-
@param obj <Any>
@returns <Integer>
*/
private fn findObserver obj = (
local index = -1
if this.isValidObserver obj do (
index = 0
)
for i = 1 to this.observers.Count while index == 0 do (
if this.observers[i] == obj do (
index = i
)
)
index
),
/*-
@param obj <Any>
@returns <BooleanClass>
*/
private fn isValidObserver obj = (
classOf obj == MAXScriptFunction
),
/*- @returns <Name> */
public fn StructName = #ObservableStruct,
/*-
@param indent: <String>
@param out: <FileStream|StringStream|WindowStream> 出力先。既定値は`listener`。
@returns <OkClass>
*/
public fn Dump indent:"" out:listener = (
format "%ObservableStruct\n" indent to:out
format "% observers:%\n" indent this.observers.Count to:out
for i = 1 to this.observers.Count do (
format "% [%]:%\n" indent i this.observers[i] to:out
)
ok
),
/*-
@param obj <Any>
@returns <BooleanClass>
@remarks 大文字と小文字を区別する。
*/
public fn Equals obj = (
local isEqualStructName = isStruct obj \
and isProperty obj #StructName \
and classOf obj.StructName == MAXScriptFunction \
and obj.StructName() == this.StructName()
local isEqualProperties = true
isEqualStructName and isEqualProperties
),
on Create do ()
)