-
Notifications
You must be signed in to change notification settings - Fork 0
Custom Element
mumlが提供するmumlBuilder
マクロを利用することで、開発者は新しい独自のElementを追加することができます。
このマクロはCustom Elementの型を与えることで、フィールドを読み出すための煩雑なJSON解析処理を自動生成します。
独自のElementとそれに対するフレーム処理はmock-upのプラグイン上で統合されます。
Custom ElementはmumlRootElement
型を継承するref object
である必要があります。これは、全てのElementをイテレータによって取得することができるようにするためです。
一方で、Custom Elementのフィールドとして存在する構造体はobject
型であることが推奨されます。ref object
型でも動作しますが、今後のアップデートでコンパイルエラーを検出するように変更する予定です。
type
myEnum = enum
me1, me2, me3
nest2 = object
nest2_field1: int8
nest2_field2: myEnum
nest1 = object
nest1_field1: float
nest1_field2: nest2
newElement = ref object of mumlRootElement
field1: Animation[int]
field2: string
field3: nest1
mumlBuilder(newElement)
次のようなJSONを上のnewElement
に変換することができます。
let newElementMuml = %* {
"field1": [1, 2, 3],
"field2": "hello!",
"field3": {
"nest1_field1": 2.5,
"nest1_field2": {
"nest2_field1": 10,
"nest2_field2": "me1"
}
}
}
echo newElement(parse_newElement(newElementMuml))[]
# => (field1: @[1, 2, 3], field2: "hello!", field3: (nest1_field1: 2.5, nest1_field2: (nest2_field1: 10, nest2_field2: me1)), default_content: "")
現在、mumlがサポートしている型は以下の通りです。構造体は何度ネストしても解釈できますが、以下の型のみで構成されている必要があります。
int, int8, float, string, enum
動的配列seq[T]
型の別名である、Animation[T]
型を提供しています。
Custom Elementが持つフィールドのうち、フレーム再生により値が変化するものはAnimation
型で包む必要があります。
mumlBuilder
マクロは大きく分けて2つの仕事をします。
1つ目は与えられた型を解析してdeserializeルールを作成すること、2つ目はルールを用いてCustom Elementのパーザを生成することです。先ほどのnewElement
型のルールは以下のように出力されます。
{
"type": "newElement",
"@field1": "int",
"field2": "string",
"field3": {
"type": "nest1",
"nest1_field1": "float",
"nest1_field2": {
"type": "nest2",
"nest2_field1": "int8",
"nest2_field2": "enum:myEnum"
}
}
}
出力されるパーザはparse_xxx
(newElement
型の場合はparse_newElement
)プロシージャと命名されます。
せっかくなので出力されるプロシージャも眺めてみます(変数名は環境によって異なる場合があります)。
proc parse_newElement(muml`gensym17: mumlNode): mumlRootElement =
var resultElement_627027 = newElement()
for key_627027, val_627027 in pairs(muml`gensym17):
case key_627027
of "field1":
for jsonArrayElement`gensym18 in items(val_627027):
add(resultElement_627027.field1, getInt(jsonArrayElement`gensym18, 0))
of "field2":
resultElement_627027.field2 = removeDoubleQuotation(getStr(val_627027, ""))
of "field3":
var resultElement_919749 = nest1()
for key_919749, val_919749 in pairs(val_627027):
case key_919749
of "nest1_field1":
resultElement_919749.nest1_field1 = getFloat(val_919749, 0.0)
of "nest1_field2":
var resultElement_353555 = nest2()
for key_353555, val_353555 in pairs(val_919749):
case key_353555
of "nest2_field1":
resultElement_353555.nest2_field1 = int8(getInt(val_353555, 0))
of "nest2_field2":
resultElement_353555.nest2_field2 = parseEnum(
removeDoubleQuotation(getStr(val_353555, "")))
resultElement_919749.nest1_field2 = resultElement_353555
resultElement_627027.field3 = resultElement_919749
result = resultElement_627027