feat: 声明 baseTask 的任务直接覆盖同名任务 (#7016)

This commit is contained in:
zzyyyl
2023-10-22 23:49:31 +08:00
committed by GitHub
6 changed files with 195 additions and 36 deletions

View File

@@ -170,12 +170,9 @@ Base task 的逻辑优先于 template task。这意味着 `"B@A": { "baseTask":
#### 多文件任务
- 后加载的任务文件 (例如外服 `tasks.json`; 下称文件二) 中定义的同名任务直接继承先加载的任务文件 (例如国服 `tasks.json`; 下称文件一) 的字段。
- 如果文件二中定义的任务在文件一中也定义了同名任务,那么:
1. 如果文件二中任务有 `baseTask` 字段,则直接继承文件一中同名任务的字段。
2. 如果文件二中任务有字段 `"baseTask": "#none"`,则不继承文件一中同名任务的字段。
- **若有定义任务 "A",则以 template task 的逻辑处理 "B@A"**
- 若未定义任务 "A",则以普通任务的逻辑处理 "B@A"
如果后加载的任务文件 (例如外服 `tasks.json`; 下称文件二) 中定义的任务在先加载的任务文件 (例如国服 `tasks.json`; 下称文件一) 中也定义了同名任务,那么:
- 如果文件二中任务没有 `baseTask` 字段,则直接继承文件一中同名任务的字段。
- 如果文件二中任务有 `baseTask` 字段,则继承文件一中同名任务的字段,而是直接覆盖
### Virtual Task虚任务

View File

@@ -163,12 +163,9 @@ Any parameter that is not explicitly defined uses the value of the `baseTask` pa
#### Multi-File Task
- A task with the same name defined in a later loaded task file (e.g. `tasks.json` for foreign services; hereinafter called File 2) inherits directly from the fields of the first loaded task file (e.g. `tasks.json` for official services; hereinafter called File 1).
- If a task defined in File 2 also has a task of the same name defined in File 1, then.
1. if the task in File 2 does not have a `baseTask` field, then it inherits the fields of the task with the same name in File 1 directly.
2. If the task in File 2 has the field `"baseTask": "#none"`, then it does not inherit the fields of the task with the same name in File 1.
- **If task "A" is defined, then "B@A" will be treated as template task**
- If task "A" is not defined, then "B@A" will be treated as a normal task
If a task defined in a later loaded task file (e.g. `tasks.json` for foreign services; hereinafter called File 2) also has a task of the same name defined in a earlier loaded task file (e.g. `tasks.json` for official services; hereinafter called File 1), then.
- if the task in File 2 does not have a `baseTask` field, then it inherits the fields of the task with the same name in File 1 directly.
- If the task in File 2 has a `baseTask` field, then it does not inherit the fields of the task with the same name in File 1, but overwrites them.
### Virtual Task
@@ -226,6 +223,48 @@ Task.get_raw("B@Loading")->next = { "B#self", "B#next", "B#back" };
In this case above, `"C@B" -> next` (i.e. `C@A#next`) is `["N1"]` instead of `["C@N0"]`.
## Runtime task modification
- `Task.lazy_parse()` loads the json task configuration file at runtime. The lazy_parse rules are the same as for [multi-file task](#multi-file task).
- `Task.set_task_base()` modifies the `baseTask` field of a task.
### Usage Example
Suppose you have the following task configuration file:
```json
{
"A": {
"baseTask": "A_default"
},
"A_default": {
"next": [ "xxx" ]
},
"A_mode1": {
"next": [ "yyy" ]
},
"A_mode2": {
"next": [ "zzz" ]
}
}
```
The following code enables changing task "A" based on the value of `mode`, and will also change other tasks that depend on task "A", e.g. "B@A":
```cpp
switch (mode) {
case 1:
Task.set_task_base("A", "A_mode1"); // This is basically the same as replacing A with the contents of A_mode1, as follows
break;
case 2:
Task.set_task_base("A", "A_mode2");
break;
default:
Task.set_task_base("A", "A_default");
break;
}
```
## Expression Calculation
| Symbol | Meaning | Example |

View File

@@ -163,12 +163,9 @@ Any parameter that is not explicitly defined uses the value of the `baseTask` pa
#### Multi-File Task
- A task with the same name defined in a later loaded task file (e.g. `tasks.json` for foreign services; hereinafter called File 2) inherits directly from the fields of the first loaded task file (e.g. `tasks.json` for official services; hereinafter called File 1).
- If a task defined in File 2 also has a task of the same name defined in File 1, then.
1. if the task in File 2 does not have a `baseTask` field, then it inherits the fields of the task with the same name in File 1 directly.
2. If the task in File 2 has the field `"baseTask": "#none"`, then it does not inherit the fields of the task with the same name in File 1.
- **If task "A" is defined, then "B@A" will be treated as template task**
- If task "A" is not defined, then "B@A" will be treated as a normal task
If a task defined in a later loaded task file (e.g. `tasks.json` for foreign services; hereinafter called File 2) also has a task of the same name defined in a earlier loaded task file (e.g. `tasks.json` for official services; hereinafter called File 1), then.
- if the task in File 2 does not have a `baseTask` field, then it inherits the fields of the task with the same name in File 1 directly.
- If the task in File 2 has a `baseTask` field, then it does not inherit the fields of the task with the same name in File 1, but overwrites them.
### Virtual Task
@@ -226,6 +223,48 @@ Task.get_raw("B@Loading")->next = { "B#self", "B#next", "B#back" };
In this case above, `"C@B" -> next` (i.e. `C@A#next`) is `["N1"]` instead of `["C@N0"]`.
## Runtime task modification
- `Task.lazy_parse()` loads the json task configuration file at runtime. The lazy_parse rules are the same as for [multi-file task](#multi-file task).
- `Task.set_task_base()` modifies the `baseTask` field of a task.
### Usage Example
Suppose you have the following task configuration file:
```json
{
"A": {
"baseTask": "A_default"
},
"A_default": {
"next": [ "xxx" ]
},
"A_mode1": {
"next": [ "yyy" ]
},
"A_mode2": {
"next": [ "zzz" ]
}
}
```
The following code enables changing task "A" based on the value of `mode`, and will also change other tasks that depend on task "A", e.g. "B@A":
```cpp
switch (mode) {
case 1:
Task.set_task_base("A", "A_mode1"); // This is basically the same as replacing A with the contents of A_mode1, as follows
break;
case 2:
Task.set_task_base("A", "A_mode2");
break;
default:
Task.set_task_base("A", "A_default");
break;
}
```
## Expression Calculation
| Symbol | Meaning | Example |

View File

@@ -156,16 +156,11 @@
명시적으로 정의되지 않은 모든 매개변수는 해당 작업이 접두사 없이 기반 작업의 매개변수를 사용하며, `template`은 명시적으로 정의되지 않은 경우에는 여전히 `"작업이름.png"`입니다.
#### 여러 파일 작업
#### Multi-File Task
- 나중에 로드된 작업 파일 (예: 외부 서비스용 `tasks.json` 파일)에서 동일한 이름으로 정의된 작업은 첫 번째 로드된 공식 서비스용 `tasks.json` 파일에서의 매개변수를 직접 상속합니다.
- 파일 2에 정의된 작업에도 공식 서비스용 `tasks.json` 파일의 동일한 이름으로 정의된 작업이 있는 경우
1. 파일 2의 작업에 `baseTask` 필드가 없는 경우 해당 작업은 파일 1의 동일한 이름을 가진 작업의 매개변수를 직접 상속합니다.
2. 파일 2의 작업에 `"baseTask": "#none"` 필드가 있는 경우 해당 작업은 파일 1의 동일한 이름을 가진 작업의 매개변수를 상속하지 않습니다.
> _참고: 파일 2에 "A" 작업이 정의된 경우, "B@A"는 파일 1의 "A" 작업의 매개변수가 아닌 "A" 작업 자체로 처리됩니다._
>
If a task defined in a later loaded task file (e.g. `tasks.json` for foreign services; hereinafter called File 2) also has a task of the same name defined in a earlier loaded task file (e.g. `tasks.json` for official services; hereinafter called File 1), then.
- if the task in File 2 does not have a `baseTask` field, then it inherits the fields of the task with the same name in File 1 directly.
- If the task in File 2 has a `baseTask` field, then it does not inherit the fields of the task with the same name in File 1, but overwrites them.
### 가상 작업
@@ -223,6 +218,48 @@ Task.get_raw("B@Loading")->next = { "B#self", "B#next", "B#back" };
위의 예시에서, `"C@B" -> next` (즉, `C@A#next`)는 `["N1"]`이 아닌 `["C@N0"]`입니다.
## Runtime task modification
- `Task.lazy_parse()` loads the json task configuration file at runtime. The lazy_parse rules are the same as for [multi-file task](#multi-file task).
- `Task.set_task_base()` modifies the `baseTask` field of a task.
### Usage Example
Suppose you have the following task configuration file:
```json
{
"A": {
"baseTask": "A_default"
},
"A_default": {
"next": [ "xxx" ]
},
"A_mode1": {
"next": [ "yyy" ]
},
"A_mode2": {
"next": [ "zzz" ]
}
}
```
The following code enables changing task "A" based on the value of `mode`, and will also change other tasks that depend on task "A", e.g. "B@A":
```cpp
switch (mode) {
case 1:
Task.set_task_base("A", "A_mode1"); // This is basically the same as replacing A with the contents of A_mode1, as follows
break;
case 2:
Task.set_task_base("A", "A_mode2");
break;
default:
Task.set_task_base("A", "A_default");
break;
}
```
## 표현식 계산
| 기호 | 의미 | 예시 |

View File

@@ -170,12 +170,9 @@ Base task 的邏輯優先於 template task。這代表 `"B@A": { "baseTask": "C"
#### 多檔任務
- 後載入的任務檔案(例如外服 `tasks.json`,下稱文件二)中定義的同名任務直接繼承先載入的任務檔案(例如國服 `tasks.json`,下稱文件一)的欄位。
- 如果文件二中定義的任務在文件一中也定義了同名任務,那麼:
1. 如果文件二中任務有 `baseTask` 欄位,則直接繼承文件一中同名任務的欄位。
2. 如果文件二中任務有欄位 `"baseTask": "#none"`,則不繼承文件一中同名任務的欄位。
- **若有定義任務 "A",則以 template task 的邏輯處理 "B@A"**
- 若未定義任務 "A",則以普通任務的邏輯處理 "B@A"
如果後載入的任務檔案(例如外服 `tasks.json`,下稱文件二)中定義的任務在先載入的任務檔案(例如國服 `tasks.json`,下稱文件一)中也定義了同名任務,那麼:
- 如果文件二中任務沒有 `baseTask` 欄位,則直接繼承文件一中同名任務的欄位。
- 如果文件二中任務有 `baseTask` 欄位,則繼承文件一中同名任務的欄位,而是直接取代
### Virtual Task虛任務
@@ -233,6 +230,48 @@ Task.get_raw("B@Loading")->next = { "B#self", "B#next", "B#back" };
以上這種情況,`"C@B" -> next`(即 `C@A#next`)為 `[ "N1" ]` 而不是 `[ "C@N0" ]`.
## 運行時修改任務
- `Task.lazy_parse()` 可以在執行時載入 json 任務設定檔。 lazy_parse 規則與[多檔任務](#多檔任務)相同。
- `Task.set_task_base()` 可以修改任務的 `baseTask` 欄位。
### 使用範例
假設有任務設定檔如下:
```json
{
"A": {
"baseTask": "A_default"
},
"A_default": {
"next": [ "xxx" ]
},
"A_mode1": {
"next": [ "yyy" ]
},
"A_mode2": {
"next": [ "zzz" ]
}
}
```
以下程式碼可以實現根據 mode 的值改變任務 "A",同時會改變其它依賴任務 "A" 的任務,如 "B@A":
```cpp
switch (mode) {
case 1:
Task.set_task_base("A", "A_mode1"); // 基本上相當於用 A_mode1 的內容直接取代 A下同
break;
case 2:
Task.set_task_base("A", "A_mode2");
break;
default:
Task.set_task_base("A", "A_default");
break;
}
```
## 運算式計算
| 符號 | 含義 | 實例 |

View File

@@ -93,10 +93,18 @@ bool asst::TaskData::lazy_parse(const json::value& json)
for (const auto& [name, task_json] : json.as_object()) {
std::string_view name_view = task_name_view(name);
if (task_json.get("baseTask", "") == "#none") {
// 不继承同名任务参数
if (task_json.contains("baseTask")) {
// 直接声明 baseTask 的任务不继承同名任务参数而是直接覆盖
m_json_all_tasks_info[name_view] = task_json.as_object();
m_json_all_tasks_info[name_view].erase("baseTask");
std::string base_task = task_json.get("baseTask", "");
#ifdef ASST_DEBUG
if (base_task.empty()) {
Log.error("Task", name, "has empty baseTask");
}
#endif
if (base_task == "#none") {
m_json_all_tasks_info[name_view].erase("baseTask");
}
continue;
}
if (m_json_all_tasks_info.find(name_view) == m_json_all_tasks_info.cend()) {