Added API version and hashing to ObjectTypeDB

This commit is contained in:
Juan Linietsky 2016-09-14 19:37:37 -03:00
parent a4156f1f0a
commit a75f5f039e
5 changed files with 212 additions and 2 deletions

View File

@ -189,6 +189,14 @@ MethodDefinition _MD(const char* p_name,const char *p_arg1,const char *p_arg2,co
#endif
ObjectTypeDB::APIType ObjectTypeDB::current_api=API_CORE;
void ObjectTypeDB::set_current_api(APIType p_api) {
current_api=p_api;
}
HashMap<StringName,ObjectTypeDB::TypeInfo,StringNameHasher> ObjectTypeDB::types;
HashMap<StringName,StringName,StringNameHasher> ObjectTypeDB::resource_base_extensions;
HashMap<StringName,StringName,StringNameHasher> ObjectTypeDB::compat_types;
@ -258,6 +266,171 @@ StringName ObjectTypeDB::type_inherits_from(const StringName& p_type) {
return ti->inherits;
}
ObjectTypeDB::APIType ObjectTypeDB::get_api_type(const StringName &p_type) {
OBJTYPE_LOCK;
TypeInfo *ti = types.getptr(p_type);
ERR_FAIL_COND_V(!ti,API_NONE);
return ti->api;
}
uint64_t ObjectTypeDB::get_api_hash(APIType p_api) {
#ifdef DEBUG_METHODS_ENABLED
uint64_t hash = hash_djb2_one_64(HashMapHahserDefault::hash(VERSION_FULL_NAME));
List<StringName> names;
const StringName *k=NULL;
while((k=types.next(k))) {
names.push_back(*k);
}
//must be alphabetically sorted for hash to compute
names.sort_custom<StringName::AlphCompare>();
for (List<StringName>::Element *E=names.front();E;E=E->next()) {
TypeInfo *t = types.getptr(E->get());
ERR_FAIL_COND_V(!t,0);
if (t->api!=p_api)
continue;
hash = hash_djb2_one_64(t->name.hash(),hash);
hash = hash_djb2_one_64(t->inherits.hash(),hash);
{ //methods
List<StringName> snames;
k=NULL;
while((k=t->method_map.next(k))) {
snames.push_back(*k);
}
snames.sort_custom<StringName::AlphCompare>();
for (List<StringName>::Element *F=snames.front();F;F=F->next()) {
MethodBind *mb = t->method_map[F->get()];
hash = hash_djb2_one_64( mb->get_name().hash(), hash);
hash = hash_djb2_one_64( mb->get_argument_count(), hash);
hash = hash_djb2_one_64( mb->get_argument_type(-1), hash); //return
for(int i=0;i<mb->get_argument_count();i++) {
hash = hash_djb2_one_64( mb->get_argument_info(i).type, hash );
hash = hash_djb2_one_64( mb->get_argument_info(i).name.hash(), hash );
hash = hash_djb2_one_64( mb->get_argument_info(i).hint, hash );
hash = hash_djb2_one_64( mb->get_argument_info(i).hint_string.hash(), hash );
}
hash = hash_djb2_one_64( mb->get_default_argument_count(), hash);
for(int i=0;i<mb->get_default_argument_count();i++) {
//hash should not change, i hope for tis
Variant da = mb->get_default_argument(i);
hash = hash_djb2_one_64( da.hash(), hash );
}
hash = hash_djb2_one_64( mb->get_hint_flags(), hash);
}
}
{ //constants
List<StringName> snames;
k=NULL;
while((k=t->constant_map.next(k))) {
snames.push_back(*k);
}
snames.sort_custom<StringName::AlphCompare>();
for (List<StringName>::Element *F=snames.front();F;F=F->next()) {
hash = hash_djb2_one_64(F->get().hash(), hash);
hash = hash_djb2_one_64( t->constant_map[F->get()], hash);
}
}
{ //signals
List<StringName> snames;
k=NULL;
while((k=t->signal_map.next(k))) {
snames.push_back(*k);
}
snames.sort_custom<StringName::AlphCompare>();
for (List<StringName>::Element *F=snames.front();F;F=F->next()) {
MethodInfo &mi = t->signal_map[F->get()];
hash = hash_djb2_one_64( F->get().hash(), hash);
for(int i=0;i<mi.arguments.size();i++) {
hash = hash_djb2_one_64( mi.arguments[i].type, hash);
}
}
}
{ //properties
List<StringName> snames;
k=NULL;
while((k=t->property_setget.next(k))) {
snames.push_back(*k);
}
snames.sort_custom<StringName::AlphCompare>();
for (List<StringName>::Element *F=snames.front();F;F=F->next()) {
PropertySetGet *psg=t->property_setget.getptr(F->get());
hash = hash_djb2_one_64( F->get().hash(), hash);
hash = hash_djb2_one_64( psg->setter.hash(), hash);
hash = hash_djb2_one_64( psg->getter.hash(), hash);
}
}
//property list
for (List<PropertyInfo>::Element *F=t->property_list.front();F;F=F->next()) {
hash = hash_djb2_one_64( F->get().name.hash(), hash);
hash = hash_djb2_one_64( F->get().type, hash);
hash = hash_djb2_one_64( F->get().hint, hash);
hash = hash_djb2_one_64( F->get().hint_string.hash(), hash);
hash = hash_djb2_one_64( F->get().usage, hash);
}
}
return hash;
#else
return 0;
#endif
}
bool ObjectTypeDB::type_exists(const StringName &p_type) {
OBJTYPE_LOCK;
@ -309,6 +482,7 @@ void ObjectTypeDB::_add_type2(const StringName& p_type, const StringName& p_inhe
TypeInfo &ti=types[name];
ti.name=name;
ti.inherits=p_inherits;
ti.api=current_api;
if (ti.inherits) {

View File

@ -109,7 +109,13 @@ static _FORCE_INLINE_ const char* _MD(const char* m_name, ...) { return m_name;
#endif
class ObjectTypeDB {
public:
enum APIType {
API_CORE,
API_EDITOR,
API_NONE
};
public:
struct PropertySetGet {
int index;
@ -122,6 +128,7 @@ class ObjectTypeDB {
struct TypeInfo {
APIType api;
TypeInfo *inherits_ptr;
HashMap<StringName,MethodBind*,StringNameHasher> method_map;
HashMap<StringName,int,StringNameHasher> constant_map;
@ -161,6 +168,7 @@ class ObjectTypeDB {
#endif
static APIType current_api;
static void _add_type2(const StringName& p_type, const StringName& p_inherits);
public:
@ -236,6 +244,9 @@ public:
static bool is_type(const StringName &p_type,const StringName& p_inherits);
static bool can_instance(const StringName &p_type);
static Object *instance(const StringName &p_type);
static APIType get_api_type(const StringName &p_type);
static uint64_t get_api_hash(APIType p_api);
#if 0
template<class N, class M>
@ -499,6 +510,8 @@ public:
static void add_compatibility_type(const StringName& p_type,const StringName& p_fallback);
static void init();
static void set_current_api(APIType p_api);
static void cleanup();
};

View File

@ -994,8 +994,11 @@ Error Main::setup2() {
}
}
#ifdef TOOLS_ENABLED
ObjectTypeDB::set_current_api(ObjectTypeDB::API_EDITOR);
EditorNode::register_editor_types();
ObjectTypeDB::register_type<PCKPacker>(); // todo: move somewhere else
ObjectTypeDB::set_current_api(ObjectTypeDB::API_CORE);
#endif
MAIN_PRINT("Main: Load Scripts, Modules, Drivers");
@ -1022,6 +1025,8 @@ Error Main::setup2() {
_start_success=true;
locale=String();
ObjectTypeDB::set_current_api(ObjectTypeDB::API_NONE); //no more api is registered at this point
MAIN_PRINT("Main: Done");
return OK;

View File

@ -5244,6 +5244,18 @@ void EditorNode::add_plugin_init_callback(EditorPluginInitializeCallback p_callb
EditorPluginInitializeCallback EditorNode::plugin_init_callbacks[EditorNode::MAX_INIT_CALLBACKS];
int EditorNode::build_callback_count=0;
void EditorNode::add_build_callback(EditorBuildCallback p_callback) {
ERR_FAIL_COND(build_callback_count==MAX_INIT_CALLBACKS);
build_callbacks[build_callback_count++]=p_callback;
}
EditorPluginInitializeCallback EditorNode::build_callbacks[EditorNode::MAX_BUILD_CALLBACKS];
void EditorNode::_bind_methods() {

View File

@ -95,6 +95,7 @@
typedef void (*EditorNodeInitCallback)();
typedef void (*EditorPluginInitializeCallback)();
typedef void (*EditorBuildCallback)();
class EditorPluginList;
@ -580,13 +581,17 @@ private:
void _toggle_distraction_free_mode();
enum {
MAX_INIT_CALLBACKS=128
MAX_INIT_CALLBACKS=128,
MAX_BUILD_CALLBACKS=128
};
static int plugin_init_callback_count;
static EditorPluginInitializeCallback plugin_init_callbacks[MAX_INIT_CALLBACKS];
static int build_callback_count;
static EditorBuildCallback build_callbacks[MAX_BUILD_CALLBACKS];
protected:
void _notification(int p_what);
static void _bind_methods();
@ -754,6 +759,7 @@ public:
void get_singleton(const char* arg1, bool arg2);
static void add_init_callback(EditorNodeInitCallback p_callback) { _init_callbacks.push_back(p_callback); }
static void add_build_callback(EditorBuildCallback p_callback);