-
Notifications
You must be signed in to change notification settings - Fork 0
JSON Inheritance
In both Box and Style objects the base
property
could be specified, which takes a string
with the name of a Box or a Style to derive respectively.
The derived object is basically the copy of the base object, extended with properties, defined in derived object.
Note. It's not necessary for the base object to be defined in the same file or only above the derived one. The requirements are that both base and derived objects must be loaded by the same box/style deserializer before retrieving any of them and there is no circular inheritance.
Note. Similar with style for box - style may be defined in another file, but the box-serializer, that deserializes the box, must use the style-serializer, that deserialized the specified style.
{
"styles": {
"base-style": {
"dialogue": {
"greeting": "Hi there!",
"farewell": "See ya!"
}
},
"derived-style": {
"base": "base-style",
"dialogue.farewell": "Bye..."
}
}
}
In this case, the "derived-style"
is equal to the next one:
{
"style": {
"dialogue": {
"greeting": "Hi there!",
"farewell": "Bye..."
}
}
}
Alternatively to the command
property,
an insert-commands
property
may be specified. It takes an array of command insert blocks
.
Each command insert block
contains a commands
property,
which is absolutely identical to the same box property;
and one of three position specifiers:
-
at
- takes either"top"
or"bottom"
as a value, and inserts the commands at the beginning or at the end respectively. -
above
- takes the name of the executable to place the commands above. -
below
- takes the name of the executable to place the commands below.
Example:
{
"insert-commands": [
{
"at": "top",
"commands": ["foo"]
},
{
"above": "foo",
"commands": ["bar"]
},
{
"below": "bar",
"commands": ["baz"]
}
]
}
The order would be:
- bar
- baz
- foo
Note. Inserts into nested namespaces currently are not supported.
Note. In this section, yaml is used instead of json for clarity. Check out this page for more info
Let's say you have a base box chatter
,
and two derived boxes - joyful-chatter
and sad-chatter
:
chatter:
commands:
- greet
joyful-chatter:
base: chatter
commands:
- cheer
sad-chatter:
base: chatter
commands:
- upset
Both joyful-chatter
& sad-chatter
got greet
command from chatter
box.
Now let's assume you want to have the same action appointed to the greet
command
for both derived boxes. But a box is deserialized into an instruction
on how to construct the corresponding BoxBuilder, rather than BoxBuilders instance itself.
So changing the deserialized chatter
won't affect the derived boxes
And you would have to duplicate the action appointment
for both joyful-chatter
and sad-chatter
like so:
// assume that `deserializer` is an Deserializer instance,
// fed with yaml specification above
Box joyful = deserializer.Boxes["joyful-chatter"]
.SetAction("greet",
context => Console.WriteLine("Hi there!"))
.Build();
Box sad = deserializer.Boxes["sad-chatter"]
.SetAction("greet",
context => Console.WriteLine("Hi there!"))
.Build();
BoxSerializer allows "extending" an instruction, i.e. append an extra step for BoxBuilder constructing process. Moreover, a derived box is just an instruction on what to add to the base box, which in turn is constructed with its own instruction. So extending the base box would affect the derived boxes as well. It could be done as follows:
deserializer.Boxes.Extend(
"chatter",
builder => builder.SetAction(
"greet",
context => Console.WriteLine("Hi there!")
)
);
So after retrieving joyful-chatter
or sad-chatter
they would have
the action for greet
command already set!
("derived-style"
from Inheritance)
{
"boxes": {
"common": {
"style": "derived-style",
"commands": [
"main",
"exit"
]
},
"derived": {
"style": {
"base": "derived-style",
"dialogue.greeting": "Welcome!"
},
"insert-commands": [
{
"above": "exit",
"commands": ["help"]
}
]
}
}
}
- General:
- File Specification:
- Templates:
- Tips