Now more than one Navigation Server can be registered.

This commit is contained in:
Relintai 2023-04-16 17:42:34 +02:00
parent fbfbbd3e00
commit 7068f1834e
4 changed files with 103 additions and 10 deletions

View File

@ -52,7 +52,8 @@ NavigationServer *new_server() {
void register_navigation_types(ModuleRegistrationLevel p_level) { void register_navigation_types(ModuleRegistrationLevel p_level) {
if (p_level == MODULE_REGISTRATION_LEVEL_SINGLETON) { if (p_level == MODULE_REGISTRATION_LEVEL_SINGLETON) {
NavigationServerManager::set_default_server(new_server); NavigationServerManager::register_server("PandemoniumNavigation", new_server);
NavigationServerManager::set_default_server("PandemoniumNavigation");
#ifndef _3D_DISABLED #ifndef _3D_DISABLED
_nav_mesh_generator = memnew(NavigationMeshGenerator); _nav_mesh_generator = memnew(NavigationMeshGenerator);

View File

@ -30,6 +30,7 @@
#include "navigation_server.h" #include "navigation_server.h"
#include "core/config/project_settings.h"
#include "scene/3d/navigation_mesh_instance.h" #include "scene/3d/navigation_mesh_instance.h"
#include "scene/resources/navigation_mesh.h" #include "scene/resources/navigation_mesh.h"
@ -118,13 +119,63 @@ NavigationServer::~NavigationServer() {
singleton = nullptr; singleton = nullptr;
} }
NavigationServerCallback NavigationServerManager::create_callback = nullptr; Vector<NavigationServerManager::ClassInfo> NavigationServerManager::navigation_servers;
int NavigationServerManager::default_server_id = -1;
int NavigationServerManager::default_server_priority = -1;
const String NavigationServerManager::setting_property_name("navigation/3d/navigation_engine");
void NavigationServerManager::set_default_server(NavigationServerCallback p_callback) { void NavigationServerManager::on_servers_changed() {
create_callback = p_callback; String navigation_servers2("DEFAULT");
for (int i = get_servers_count() - 1; 0 <= i; --i) {
navigation_servers2 += "," + get_server_name(i);
}
ProjectSettings::get_singleton()->set_custom_property_info(setting_property_name, PropertyInfo(Variant::STRING, setting_property_name, PROPERTY_HINT_ENUM, navigation_servers2));
}
void NavigationServerManager::register_server(const String &p_name, CreateNavigationServerCallback p_creat_callback) {
ERR_FAIL_COND(!p_creat_callback);
ERR_FAIL_COND(find_server_id(p_name) != -1);
navigation_servers.push_back(ClassInfo(p_name, p_creat_callback));
on_servers_changed();
}
void NavigationServerManager::set_default_server(const String &p_name, int p_priority) {
const int id = find_server_id(p_name);
ERR_FAIL_COND(id == -1); // Not found
if (default_server_priority < p_priority) {
default_server_id = id;
default_server_priority = p_priority;
}
}
int NavigationServerManager::find_server_id(const String &p_name) {
for (int i = navigation_servers.size() - 1; 0 <= i; --i) {
if (p_name == navigation_servers[i].name) {
return i;
}
}
return -1;
}
int NavigationServerManager::get_servers_count() {
return navigation_servers.size();
}
String NavigationServerManager::get_server_name(int p_id) {
ERR_FAIL_INDEX_V(p_id, get_servers_count(), "");
return navigation_servers[p_id].name;
} }
NavigationServer *NavigationServerManager::new_default_server() { NavigationServer *NavigationServerManager::new_default_server() {
ERR_FAIL_COND_V(create_callback == nullptr, nullptr); ERR_FAIL_COND_V(default_server_id == -1, nullptr);
return create_callback(); return navigation_servers[default_server_id].create_callback();
} }
NavigationServer *NavigationServerManager::new_server(const String &p_name) {
int id = find_server_id(p_name);
if (id == -1) {
return nullptr;
} else {
return navigation_servers[id].create_callback();
}
}

View File

@ -30,8 +30,8 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/ /*************************************************************************/
#include "core/object/object.h"
#include "core/containers/rid.h" #include "core/containers/rid.h"
#include "core/object/object.h"
#include "core/object/reference.h" #include "core/object/reference.h"
@ -217,15 +217,52 @@ public:
virtual ~NavigationServer(); virtual ~NavigationServer();
}; };
typedef NavigationServer *(*NavigationServerCallback)(); typedef NavigationServer *(*CreateNavigationServerCallback)();
/// Manager used for the server singleton registration /// Manager used for the server singleton registration
class NavigationServerManager { class NavigationServerManager {
static NavigationServerCallback create_callback; struct ClassInfo {
String name;
CreateNavigationServerCallback create_callback;
ClassInfo() :
name(""),
create_callback(nullptr) {}
ClassInfo(String p_name, CreateNavigationServerCallback p_create_callback) :
name(p_name),
create_callback(p_create_callback) {}
ClassInfo(const ClassInfo &p_ci) :
name(p_ci.name),
create_callback(p_ci.create_callback) {}
ClassInfo operator=(const ClassInfo &p_ci) {
name = p_ci.name;
create_callback = p_ci.create_callback;
return *this;
}
};
static Vector<ClassInfo> navigation_servers;
static int default_server_id;
static int default_server_priority;
public: public:
static void set_default_server(NavigationServerCallback p_callback); static const String setting_property_name;
private:
static void on_servers_changed();
public:
static void register_server(const String &p_name, CreateNavigationServerCallback p_create_callback);
static void set_default_server(const String &p_name, int p_priority = 0);
static int find_server_id(const String &p_name);
static int get_servers_count();
static String get_server_name(int p_id);
static NavigationServer *new_default_server(); static NavigationServer *new_default_server();
static NavigationServer *new_server(const String &p_name);
}; };
#endif #endif

View File

@ -190,6 +190,10 @@ void register_server_types() {
PhysicsServerManager::register_server("PandemoniumPhysics", &_createPandemoniumPhysicsCallback); PhysicsServerManager::register_server("PandemoniumPhysics", &_createPandemoniumPhysicsCallback);
PhysicsServerManager::set_default_server("PandemoniumPhysics"); PhysicsServerManager::set_default_server("PandemoniumPhysics");
// Navigation 3D
GLOBAL_DEF(NavigationServerManager::setting_property_name, "DEFAULT");
ProjectSettings::get_singleton()->set_custom_property_info(NavigationServerManager::setting_property_name, PropertyInfo(Variant::STRING, NavigationServerManager::setting_property_name, PROPERTY_HINT_ENUM, "DEFAULT"));
} }
void unregister_server_types() { void unregister_server_types() {