Example #1
0
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;
}
Example #2
0
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;
	}
Example #4
0
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;
}
Example #5
0
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;
}