-
Notifications
You must be signed in to change notification settings - Fork 23
/
FeatureState.ts
161 lines (131 loc) · 4.06 KB
/
FeatureState.ts
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
152
153
154
155
156
157
158
159
160
161
import type { StyleManager } from "./style_manager";
import { FeatureState as ExprFeatureState } from "./expression";
/**
* 特定のフィーチャに独自のプロパティを割り当てる。
*
* スタイルで `["feature-state", "prop-name"]` のような式を評価すると、
* そのフィーチャーに対する `FeatureState` インスタンスに設定した
* `"prop-name"` プロパティの値が得られる。
*
* ただし `"prop-name"` プロパティが存在しないとき、またはフィーチャーに
* 対する `FeatureState` インスタンスが存在しないときは `null` が得られる。
*
* `FeatureState` インスタンスは [[StyleManager.ensureFeatureState]]
* により生成することができる。
*/
export class FeatureState {
/**
* 起源となる [[StyleManager]] インスタンス
*/
public readonly style_manager: StyleManager;
/**
* 対応するフィーチャの ID
*/
public readonly feature_id: number;
/**
* プロパティ評価用のフィーチャ状態
*
* @internal
*/
public readonly __content: ExprFeatureState;
/**
* 保有するプロパティの数
*/
get num_properties(): number
{
return this._pid_set.size;
}
/**
* プロパティの値を設定する。
*
* `pid` に対応するプロパティの値を `value` に設定する。
*
* プロパティが存在しないときは、新規にプロパティを生成して値を
* `value` に設定する。
*
* @remarks
* `value` はそのまま this に保持される (複製されない) ので、`value` が
* 参照型のときはその内容を変更しないこと。
*/
setValue( pid: string,
value: unknown ): void
{
if ( !this._pid_set.has( pid ) ) {
// プロパティを新規に追加
this._pid_set.add( pid );
}
// プロパティの値を更新
this.__content[pid] = value;
}
/**
* プロパティの値を取得する。
*
* `pid` に対応するプロパティの値を取得する。
*
* プロパティが存在しない場合は `undefined` を返す。
*/
getValue( pid: string ): unknown | undefined
{
return this.__content[pid];
}
/**
* 所有するプロパティの ID を列挙するオブジェクトを取得する。
*/
getPropertyIds(): IterableIterator<string>
{
return this._pid_set.values();
}
/**
* 指定したプロパティの所有を確認する。
*
* `pid` に対応するプロパティを所有していれば `true`, 所有していな
* ければ `false` を返す。
*/
hasProperty( pid: string ): boolean
{
return this._pid_set.has( pid );
}
/**
* 所有するすべてのプロパティを削除する。
*/
clearProperties(): void
{
for ( const pid of this._pid_set ) {
delete this.__content[pid];
}
this._pid_set.clear();
}
/**
* 指定したプロパティを削除する。
*
* `pid` に対応するプロパティを削除する。
*
* そのプロパティが存在しなければ何もしない。
*/
deleteProperty( pid: string ): void
{
if ( this._pid_set.has( pid ) ) {
delete this.__content[pid];
this._pid_set.delete( pid );
}
}
/**
* 内部用のインスタンス生成
*
* @internal
*/
public static __create( owner: StyleManager,
feature_id: number ): FeatureState
{
return new FeatureState( owner, feature_id );
}
private constructor( owner: StyleManager,
feature_id: number )
{
this.style_manager = owner;
this.feature_id = feature_id;
this._pid_set = new Set();
this.__content = {};
}
private readonly _pid_set: Set<string>;
}