add '...@append' method to block properties

This commit is contained in:
MihailRis 2024-12-29 08:56:47 +03:00
parent d57e46297b
commit ebea9af380
4 changed files with 56 additions and 2 deletions

View File

@ -213,3 +213,11 @@ User properties must be declared in `pack:config/user-props.toml` file:
```
Example: [user properties of pack **base**](../../res/content/base/config/user-props.toml).
## Methods
Methods are used to manage the overwriting of properties when extending a block with other packs.
### `property_name@append`
Adds elements to the end of the list instead of completely overwriting it.

View File

@ -224,3 +224,11 @@
```
Пример: [пользовательские свойства пака **base**](../../res/content/base/config/user-props.toml).
## Методы
Методы используются для управлением перезаписью свойств при расширении блока другими паками.
### `имя_свойства@append`
Добавляет элементы в конец списка, вместо его полной перезаписи.

View File

@ -93,8 +93,8 @@ std::unique_ptr<Content> ContentBuilder::build() {
def->rt.surfaceReplacement = content->blocks.require(def->surfaceReplacement).rt.id;
if (def->properties == nullptr) {
def->properties = dv::object();
def->properties["name"] = def->name;
}
def->properties["name"] = def->name;
}
for (ItemDef* def : itemDefsIndices) {

View File

@ -187,11 +187,49 @@ static void perform_user_block_fields(
layout = StructLayout::create(fields);
}
static void process_method(
dv::value& properties,
const std::string& method,
const std::string& name,
const dv::value& value
) {
if (method == "append") {
if (!properties.has(name)) {
properties[name] = dv::list();
}
auto& list = properties[name];
if (value.isList()) {
for (const auto& item : value) {
list.add(item);
}
} else {
list.add(value);
}
} else {
throw std::runtime_error(
"unknown method " + method + " for " + name
);
}
}
void ContentLoader::loadBlock(
Block& def, const std::string& name, const fs::path& file
) {
auto root = files::read_json(file);
def.properties = root;
if (def.properties == nullptr) {
def.properties = dv::object();
def.properties["name"] = name;
}
for (auto& [key, value] : root.asObject()) {
auto pos = key.rfind('@');
if (pos == std::string::npos) {
def.properties[key] = value;
continue;
}
auto field = key.substr(0, pos);
auto suffix = key.substr(pos + 1);
process_method(def.properties, suffix, field, value);
}
if (root.has("parent")) {
const auto& parentName = root["parent"].asString();