2023-08-25 15:32:46 +00:00
|
|
|
/**
|
|
|
|
* limbo_task_db.cpp
|
|
|
|
* =============================================================================
|
|
|
|
* Copyright 2021-2023 Serhii Snitsaruk
|
|
|
|
*
|
|
|
|
* Use of this source code is governed by an MIT-style
|
|
|
|
* license that can be found in the LICENSE file or at
|
|
|
|
* https://opensource.org/licenses/MIT.
|
|
|
|
* =============================================================================
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "limbo_task_db.h"
|
|
|
|
|
2024-01-06 20:04:34 +00:00
|
|
|
#ifdef LIMBOAI_MODULE
|
2023-08-25 15:32:46 +00:00
|
|
|
#include "core/config/project_settings.h"
|
|
|
|
#include "core/io/dir_access.h"
|
2024-01-06 20:04:34 +00:00
|
|
|
#endif // LIMBOAI_MODULE
|
|
|
|
|
|
|
|
#ifdef LIMBOAI_GDEXTENSION
|
|
|
|
#include <godot_cpp/classes/dir_access.hpp>
|
|
|
|
#include <godot_cpp/classes/project_settings.hpp>
|
|
|
|
using namespace godot;
|
|
|
|
#endif // LIMBOAI_GDEXTENSION
|
2023-08-25 15:32:46 +00:00
|
|
|
|
|
|
|
HashMap<String, List<String>> LimboTaskDB::core_tasks;
|
|
|
|
HashMap<String, List<String>> LimboTaskDB::tasks_cache;
|
|
|
|
|
|
|
|
_FORCE_INLINE_ void _populate_scripted_tasks_from_dir(String p_path, List<String> *p_task_classes) {
|
|
|
|
if (p_path.is_empty()) {
|
|
|
|
return;
|
|
|
|
}
|
2024-01-06 20:04:34 +00:00
|
|
|
|
|
|
|
#ifdef LIMBOAI_MODULE
|
2023-08-25 15:32:46 +00:00
|
|
|
Ref<DirAccess> dir = DirAccess::create(DirAccess::ACCESS_RESOURCES);
|
2024-01-06 20:04:34 +00:00
|
|
|
#endif
|
|
|
|
#ifdef LIMBOAI_GDEXTENSION
|
|
|
|
Ref<DirAccess> dir = memnew(DirAccess);
|
|
|
|
#endif
|
|
|
|
|
2023-08-25 15:32:46 +00:00
|
|
|
if (dir->change_dir(p_path) == OK) {
|
|
|
|
dir->list_dir_begin();
|
|
|
|
String fn = dir->get_next();
|
|
|
|
while (!fn.is_empty()) {
|
2023-09-16 11:22:09 +00:00
|
|
|
if (fn.ends_with(".gd") || fn.ends_with(".cs")) {
|
2023-08-25 15:32:46 +00:00
|
|
|
String full_path = p_path.path_join(fn);
|
|
|
|
p_task_classes->push_back(full_path);
|
|
|
|
}
|
|
|
|
fn = dir->get_next();
|
|
|
|
}
|
|
|
|
dir->list_dir_end();
|
|
|
|
} else {
|
|
|
|
ERR_FAIL_MSG(vformat("Failed to list \"%s\" directory.", p_path));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
_FORCE_INLINE_ void _populate_from_user_dir(String p_path, HashMap<String, List<String>> *p_categories) {
|
|
|
|
if (p_path.is_empty()) {
|
|
|
|
return;
|
|
|
|
}
|
2024-01-06 20:04:34 +00:00
|
|
|
|
|
|
|
#ifdef LIMBOAI_MODULE
|
2023-08-25 15:32:46 +00:00
|
|
|
Ref<DirAccess> dir = DirAccess::create(DirAccess::ACCESS_RESOURCES);
|
2024-01-06 20:04:34 +00:00
|
|
|
#endif
|
|
|
|
#ifdef LIMBOAI_GDEXTENSION
|
|
|
|
Ref<DirAccess> dir = memnew(DirAccess);
|
|
|
|
#endif
|
|
|
|
|
2023-08-25 15:32:46 +00:00
|
|
|
if (dir->change_dir(p_path) == OK) {
|
|
|
|
dir->list_dir_begin();
|
|
|
|
String fn = dir->get_next();
|
|
|
|
while (!fn.is_empty()) {
|
|
|
|
if (dir->current_is_dir() && fn != "..") {
|
|
|
|
String full_path;
|
|
|
|
String category;
|
|
|
|
if (fn == ".") {
|
|
|
|
full_path = p_path;
|
|
|
|
category = LimboTaskDB::get_misc_category();
|
|
|
|
} else {
|
|
|
|
full_path = p_path.path_join(fn);
|
|
|
|
category = fn.capitalize();
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!p_categories->has(category)) {
|
|
|
|
p_categories->insert(category, List<String>());
|
|
|
|
}
|
|
|
|
|
|
|
|
_populate_scripted_tasks_from_dir(full_path, &p_categories->get(category));
|
|
|
|
}
|
|
|
|
fn = dir->get_next();
|
|
|
|
}
|
|
|
|
dir->list_dir_end();
|
|
|
|
} else {
|
|
|
|
ERR_FAIL_MSG(vformat("Failed to list \"%s\" directory.", p_path));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void LimboTaskDB::scan_user_tasks() {
|
|
|
|
tasks_cache = HashMap<String, List<String>>(core_tasks);
|
|
|
|
|
|
|
|
if (!tasks_cache.has(LimboTaskDB::get_misc_category())) {
|
|
|
|
tasks_cache[LimboTaskDB::get_misc_category()] = List<String>();
|
|
|
|
}
|
|
|
|
|
|
|
|
for (int i = 1; i < 4; i++) {
|
2024-01-06 20:04:34 +00:00
|
|
|
String dir1 = ProjectSettings::get_singleton()->get_setting_with_override("limbo_ai/behavior_tree/user_task_dir_" + itos(i));
|
2023-08-25 15:32:46 +00:00
|
|
|
_populate_from_user_dir(dir1, &tasks_cache);
|
|
|
|
}
|
2023-08-25 16:08:18 +00:00
|
|
|
|
|
|
|
for (KeyValue<String, List<String>> &E : tasks_cache) {
|
|
|
|
E.value.sort_custom<ComparatorByTaskName>();
|
|
|
|
}
|
2023-08-25 15:32:46 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
List<String> LimboTaskDB::get_categories() {
|
|
|
|
List<String> r_cat;
|
|
|
|
for (const KeyValue<String, List<String>> &E : tasks_cache) {
|
|
|
|
r_cat.push_back(E.key);
|
|
|
|
}
|
2023-08-26 13:41:11 +00:00
|
|
|
r_cat.sort();
|
2023-08-25 15:32:46 +00:00
|
|
|
return r_cat;
|
|
|
|
}
|
|
|
|
|
|
|
|
List<String> LimboTaskDB::get_tasks_in_category(const String &p_category) {
|
|
|
|
return List<String>(tasks_cache[p_category]);
|
|
|
|
}
|