const Vector<GDMonoClass *> &GDMonoClass::get_all_delegates() { if (delegates_fetched) return delegates_list; void *iter = NULL; MonoClass *raw_class = NULL; while ((raw_class = mono_class_get_nested_types(mono_class, &iter)) != NULL) { if (mono_class_is_delegate(raw_class)) { StringName name = mono_class_get_name(raw_class); Map<StringName, GDMonoClass *>::Element *match = delegates.find(name); if (match) { delegates_list.push_back(match->get()); } else { GDMonoClass *delegate = memnew(GDMonoClass(mono_class_get_namespace(raw_class), mono_class_get_name(raw_class), raw_class, assembly)); delegates.insert(name, delegate); delegates_list.push_back(delegate); } } } delegates_fetched = true; return delegates_list; }
GDMonoClass *GDMonoAssembly::get_object_derived_class(const StringName &p_class) { GDMonoClass *match = NULL; if (gdobject_class_cache_updated) { Map<StringName, GDMonoClass *>::Element *result = gdobject_class_cache.find(p_class); if (result) match = result->get(); } else { List<GDMonoClass *> nested_classes; int rows = mono_image_get_table_rows(image, MONO_TABLE_TYPEDEF); for (int i = 1; i < rows; i++) { MonoClass *mono_class = mono_class_get(image, (i + 1) | MONO_TOKEN_TYPE_DEF); if (!mono_class_is_assignable_from(CACHED_CLASS_RAW(GodotObject), mono_class)) continue; GDMonoClass *current = get_class(mono_class); if (!current) continue; nested_classes.push_back(current); if (!match && current->get_name() == p_class) match = current; while (!nested_classes.empty()) { GDMonoClass *current_nested = nested_classes.front()->get(); nested_classes.pop_back(); void *iter = NULL; while (true) { MonoClass *raw_nested = mono_class_get_nested_types(current_nested->get_raw(), &iter); if (!raw_nested) break; GDMonoClass *nested_class = get_class(raw_nested); if (nested_class) { gdobject_class_cache.insert(nested_class->get_name(), nested_class); nested_classes.push_back(nested_class); } } } gdobject_class_cache.insert(current->get_name(), current); } gdobject_class_cache_updated = true; } return match; }
const Vector<MonoClass*>& MonoAssembly::getAllClasses() const { if(mHaveCachedClassList) return mCachedClassList; mCachedClassList.clear(); Stack<MonoClass*> todo; int numRows = mono_image_get_table_rows (mMonoImage, MONO_TABLE_TYPEDEF); for(int i = 1; i < numRows; i++) // Skip Module { ::MonoClass* monoClass = mono_class_get (mMonoImage, (i + 1) | MONO_TOKEN_TYPE_DEF); String ns; String type; MonoUtil::getClassName(monoClass, ns, type); MonoClass* curClass = getClass(ns, type); if (curClass != nullptr) { // Get nested types if it has any todo.push(curClass); while (!todo.empty()) { MonoClass* curNestedClass = todo.top(); todo.pop(); void* iter = nullptr; do { ::MonoClass* rawNestedClass = rawNestedClass = mono_class_get_nested_types(curNestedClass->_getInternalClass(), &iter); if (rawNestedClass == nullptr) break; String nestedType = curNestedClass->getTypeName() + "+" + mono_class_get_name(rawNestedClass); MonoClass* nestedClass = getClass(ns, nestedType, rawNestedClass); if (nestedClass != nullptr) { mCachedClassList.push_back(nestedClass); todo.push(nestedClass); } } while (true); } mCachedClassList.push_back(curClass); } } mHaveCachedClassList = true; return mCachedClassList; }