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; }
Error GodotSharpExport::_get_assembly_dependencies(GDMonoAssembly *p_assembly, const Vector<String> &p_search_dirs, Map<String, String> &r_dependencies) { MonoImage *image = p_assembly->get_image(); for (int i = 0; i < mono_image_get_table_rows(image, MONO_TABLE_ASSEMBLYREF); i++) { MonoAssemblyName *ref_aname = aname_prealloc; mono_assembly_get_assemblyref(image, i, ref_aname); String ref_name = mono_assembly_name_get_name(ref_aname); if (r_dependencies.find(ref_name)) continue; GDMonoAssembly *ref_assembly = NULL; String path; bool has_extension = ref_name.ends_with(".dll") || ref_name.ends_with(".exe"); for (int j = 0; j < p_search_dirs.size(); j++) { const String &search_dir = p_search_dirs[j]; if (has_extension) { path = search_dir.plus_file(ref_name); if (FileAccess::exists(path)) { GDMono::get_singleton()->load_assembly_from(ref_name.get_basename(), path, &ref_assembly, true); if (ref_assembly != NULL) break; } } else { path = search_dir.plus_file(ref_name + ".dll"); if (FileAccess::exists(path)) { GDMono::get_singleton()->load_assembly_from(ref_name, path, &ref_assembly, true); if (ref_assembly != NULL) break; } path = search_dir.plus_file(ref_name + ".exe"); if (FileAccess::exists(path)) { GDMono::get_singleton()->load_assembly_from(ref_name, path, &ref_assembly, true); if (ref_assembly != NULL) break; } } } if (!ref_assembly) { ERR_EXPLAIN("Cannot load assembly (refonly): " + ref_name); ERR_FAIL_V(ERR_CANT_RESOLVE); } r_dependencies.insert(ref_name, ref_assembly->get_path()); Error err = _get_assembly_dependencies(ref_assembly, p_search_dirs, r_dependencies); if (err != OK) return err; } return OK; }
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; }
gboolean ml_is_api_dll(MonoImage *image) { MonoClass *klass; int i, total; total = mono_image_get_table_rows (image, MONO_TABLE_TYPEDEF); for (i = 1; i <= total; ++i) { klass = mono_class_get (image, MONO_TOKEN_TYPE_DEF | i); if (strcmp(mono_class_get_name(klass), "Debug") == 0) if (strcmp(mono_class_get_namespace(klass), "Purple") == 0) { ml_set_api_image(image); return TRUE; } } return FALSE; }
MonoClass* ml_find_plugin_class(MonoImage *image) { MonoClass *klass, *pklass = NULL; int i, total; total = mono_image_get_table_rows (image, MONO_TABLE_TYPEDEF); for (i = 1; i <= total; ++i) { klass = mono_class_get (image, MONO_TOKEN_TYPE_DEF | i); pklass = mono_class_get_parent(klass); if (pklass) { if (strcmp("Plugin", mono_class_get_name(pklass)) == 0) return klass; } } return NULL; }