bool ScriptEditorWidget::createManagedInstance() { const char* assemblies[2] = { EDITOR_ASSEMBLY, SCRIPT_EDITOR_ASSEMBLY }; UINT32 numAssemblies = sizeof(assemblies) / sizeof(assemblies[0]); for (UINT32 i = 0; i < numAssemblies; i++) { MonoAssembly* assembly = MonoManager::instance().getAssembly(assemblies[i]); if (assembly != nullptr) { MonoClass* editorWindowClass = assembly->getClass(mNamespace, mTypename); if (editorWindowClass != nullptr) { mManagedInstance = editorWindowClass->createInstance(); MonoObject* guiPanel = ScriptGUIPanel::createFromExisting(mContent); mContentsPanel = ScriptGUILayout::toNative(guiPanel); ScriptEditorWindow::guiPanelField->setValue(mManagedInstance, guiPanel); reloadMonoTypes(editorWindowClass); return true; } } } return false; }
void MenuItemManager::reloadAssemblyData() { clearMenuItems(); // Reload MenuItem attribute from editor assembly MonoAssembly* editorAssembly = MonoManager::instance().getAssembly(EDITOR_ASSEMBLY); mMenuItemAttribute = editorAssembly->getClass(EDITOR_NS, "MenuItem"); if (mMenuItemAttribute == nullptr) BS_EXCEPT(InvalidStateException, "Cannot find MenuItem managed class."); mPathField = mMenuItemAttribute->getField("path"); mShortcutField = mMenuItemAttribute->getField("shortcut"); mPriorityField = mMenuItemAttribute->getField("priority"); mSeparatorField = mMenuItemAttribute->getField("separator"); MainEditorWindow* mainWindow = EditorWindowManager::instance().getMainWindow(); Vector<String> scriptAssemblyNames = mScriptObjectManager.getScriptAssemblies(); for (auto& assemblyName : scriptAssemblyNames) { MonoAssembly* assembly = MonoManager::instance().getAssembly(assemblyName); // Find new menu item methods const Vector<MonoClass*>& allClasses = assembly->getAllClasses(); for (auto curClass : allClasses) { const Vector<MonoMethod*>& methods = curClass->getAllMethods(); for (auto& curMethod : methods) { String path; ShortcutKey shortcutKey = ShortcutKey::NONE; INT32 priority = 0; bool separator = false; if (parseMenuItemMethod(curMethod, path, shortcutKey, priority, separator)) { std::function<void()> callback = std::bind(&MenuItemManager::menuItemCallback, curMethod); if (separator) { Vector<String> pathElements = StringUtil::split(path, "/"); String separatorPath; if (pathElements.size() > 1) { const String& lastElem = pathElements[pathElements.size() - 1]; separatorPath = path; separatorPath.erase(path.size() - lastElem.size() - 1, lastElem.size() + 1); } GUIMenuItem* separatorItem = mainWindow->getMenuBar().addMenuItemSeparator(separatorPath, priority); mMenuItems.push_back(separatorItem); } GUIMenuItem* menuItem = mainWindow->getMenuBar().addMenuItem(path, callback, priority, shortcutKey); mMenuItems.push_back(menuItem); } } } } }
MonoObject* ScriptDropDownWindow::internal_CreateInstance(MonoString* ns, MonoString* typeName, ScriptEditorWindow* parentWindow, Vector2I* position) { String strTypeName = MonoUtil::monoToString(typeName); String strNamespace = MonoUtil::monoToString(ns); String fullName = strNamespace + "." + strTypeName; MonoClass* windowClass = MonoManager::instance().findClass(strNamespace, strTypeName); if (windowClass == nullptr) return nullptr; MonoAssembly* assembly = MonoManager::instance().getAssembly(EDITOR_ASSEMBLY); MonoClass* defaultSizeAttrib = assembly->getClass("BansheeEditor", "DefaultSize"); if (defaultSizeAttrib == nullptr) BS_EXCEPT(InternalErrorException, "Cannot find DefaultSize managed class."); MonoField* defaultWidthField = defaultSizeAttrib->getField("width"); MonoField* defaultHeightField = defaultSizeAttrib->getField("height"); int width = 200; int height = 200; MonoObject* defaultSizeObj = windowClass->getAttribute(defaultSizeAttrib); if (defaultSizeObj != nullptr) { defaultWidthField->get(defaultSizeObj, &width); defaultHeightField->get(defaultSizeObj, &height); } MonoObject* instance = windowClass->createInstance(false); ManagedDropDownWindow* dropDownWindow = nullptr; if (parentWindow != nullptr && !parentWindow->isDestroyed()) { EditorWidgetBase* editorWidget = parentWindow->getEditorWidget(); EditorWidgetContainer* parentContainer = editorWidget->_getParent(); if (parentContainer != nullptr) { SPtr<RenderWindow> parentRenderWindow = parentContainer->getParentWindow()->getRenderWindow(); SPtr<Camera> parentCamera = parentContainer->getParentWidget().getCamera(); position->x += editorWidget->getX(); position->y += editorWidget->getY(); dropDownWindow = DropDownWindowManager::instance().open<ManagedDropDownWindow>( parentRenderWindow, parentCamera, *position, instance, width, height); } } ScriptDropDownWindow* nativeInstance = new (bs_alloc<ScriptDropDownWindow>()) ScriptDropDownWindow(dropDownWindow); if (dropDownWindow != nullptr) dropDownWindow->initialize(nativeInstance); windowClass->construct(instance); return instance; }
void ScriptEditorWindow::registerManagedEditorWindows() { MonoAssembly* assembly = MonoManager::instance().getAssembly(EDITOR_ASSEMBLY); if(assembly != nullptr) { MonoClass* defaultSizeAttrib = assembly->getClass("BansheeEditor", "DefaultSize"); if (defaultSizeAttrib == nullptr) BS_EXCEPT(InternalErrorException, "Cannot find DefaultSize managed attribute."); MonoField* defaultWidthField = defaultSizeAttrib->getField("width"); MonoField* defaultHeightField = defaultSizeAttrib->getField("height"); MonoClass* undoRedoLocalAttrib = assembly->getClass("BansheeEditor", "UndoRedoLocal"); if (undoRedoLocalAttrib == nullptr) BS_EXCEPT(InternalErrorException, "Cannot find UndoRedoLocal managed attribute."); MonoClass* editorWindowClass = assembly->getClass("BansheeEditor", "EditorWindow"); const Vector<MonoClass*>& allClasses = assembly->getAllClasses(); for(auto& curClass : allClasses) { if(curClass->isSubClassOf(editorWindowClass) && curClass != editorWindowClass) { UINT32 width = 400; UINT32 height = 400; MonoObject* defaultSize = curClass->getAttribute(defaultSizeAttrib); if (defaultSize != nullptr) { defaultWidthField->get(defaultSize, &width); defaultHeightField->get(defaultSize, &height); } bool hasLocalUndoRedo = curClass->getAttribute(undoRedoLocalAttrib) != nullptr; const String& className = curClass->getFullName(); EditorWidgetManager::instance().registerWidget(className, std::bind(&ScriptEditorWindow::openEditorWidgetCallback, curClass->getNamespace(), curClass->getTypeName(), width, height, hasLocalUndoRedo, _1)); AvailableWindowTypes.push_back(className); } } } }
void ScriptPostProcessSettings::initRuntimeData() { metaData.scriptClass->addInternalCall("Internal_CreateDefault", &ScriptPostProcessSettings::internal_CreateDefault); // Validation #if BS_DEBUG_MODE MonoAssembly* engineAssembly = MonoManager::instance().getAssembly(ENGINE_ASSEMBLY); MonoClass* autoExposureSettingsClass = engineAssembly->getClass("BansheeEngine", "AutoExposureSettings"); MonoClass* tonemappingSettingsClass = engineAssembly->getClass("BansheeEngine", "TonemappingSettings"); MonoClass* whieBalanceSettingsClass = engineAssembly->getClass("BansheeEngine", "WhiteBalanceSettings"); MonoClass* colorGradingSettingsClass = engineAssembly->getClass("BansheeEngine", "ColorGradingSettings"); assert(metaData.scriptClass->getInstanceSize() == sizeof(PostProcessSettings)); assert(autoExposureSettingsClass->getInstanceSize() == sizeof(AutoExposureSettings)); assert(tonemappingSettingsClass->getInstanceSize() == sizeof(TonemappingSettings)); assert(whieBalanceSettingsClass->getInstanceSize() == sizeof(WhiteBalanceSettings)); assert(colorGradingSettingsClass->getInstanceSize() == sizeof(ColorGradingSettings)); #endif }
void MonoManager::initializeAssembly(MonoAssembly& assembly) { if (!assembly.mIsLoaded) { assembly.load(mScriptDomain); // Fully initialize all types that use this assembly Vector<ScriptMeta*>& mTypeMetas = getScriptMetaData()[assembly.mName]; for (auto& meta : mTypeMetas) { meta->scriptClass = assembly.getClass(meta->ns, meta->name); if (meta->scriptClass == nullptr) BS_EXCEPT(InvalidParametersException, "Unable to find class of type: \"" + meta->ns + "::" + meta->name + "\""); if (meta->scriptClass->hasField("mCachedPtr")) meta->thisPtrField = meta->scriptClass->getField("mCachedPtr"); else meta->thisPtrField = nullptr; meta->initCallback(); } } if (!mIsCoreLoaded) { mIsCoreLoaded = true; MonoAssembly* corlib = nullptr; auto iterFind = mAssemblies.find("corlib"); if (iterFind == mAssemblies.end()) { corlib = new (bs_alloc<MonoAssembly>()) MonoAssembly(L"corlib", "corlib"); mAssemblies["corlib"] = corlib; } else corlib = iterFind->second; corlib->loadFromImage(mono_get_corlib()); } }
void ScriptAssemblyManager::initializeBuiltinComponentInfos() { mBuiltinComponentInfos.clear(); mBuiltinComponentInfosByTID.clear(); Vector<BuiltinComponentInfo> allComponentsInfos = BuiltinComponents::getEntries(); for(auto& entry : allComponentsInfos) { MonoAssembly* assembly = MonoManager::instance().getAssembly(entry.metaData->assembly); if (assembly == nullptr) continue; BuiltinComponentInfo info = entry; info.monoClass = assembly->getClass(entry.metaData->ns, entry.metaData->name); ::MonoReflectionType* type = MonoUtil::getType(info.monoClass->_getInternalClass()); mBuiltinComponentInfos[type] = info; mBuiltinComponentInfosByTID[info.typeId] = info; } }
void ScriptGizmoManager::reloadAssemblyData() { // Reload DrawGizmo attribute from editor assembly MonoAssembly* editorAssembly = MonoManager::instance().getAssembly(EDITOR_ASSEMBLY); mDrawGizmoAttribute = editorAssembly->getClass("BansheeEditor", "DrawGizmo"); if (mDrawGizmoAttribute == nullptr) BS_EXCEPT(InvalidStateException, "Cannot find DrawGizmo managed class."); mFlagsField = mDrawGizmoAttribute->getField("flags"); Vector<String> scriptAssemblyNames = mScriptObjectManager.getScriptAssemblies(); for (auto& assemblyName : scriptAssemblyNames) { MonoAssembly* assembly = MonoManager::instance().getAssembly(assemblyName); // Find new gizmo drawer methods const Vector<MonoClass*>& allClasses = assembly->getAllClasses(); for (auto curClass : allClasses) { const Vector<MonoMethod*>& methods = curClass->getAllMethods(); for (auto& curMethod : methods) { UINT32 drawGizmoFlags = 0; MonoClass* componentType = nullptr; if (isValidDrawGizmoMethod(curMethod, componentType, drawGizmoFlags)) { String fullComponentName = componentType->getFullName(); GizmoData& newGizmoData = mGizmoDrawers[fullComponentName]; newGizmoData.componentType = componentType; newGizmoData.drawGizmosMethod = curMethod; newGizmoData.flags = drawGizmoFlags; } } } } }
void ScriptInspectorUtility::reloadAssemblyData() { mInspectorTypes.clear(); mInspectableFieldTypes.clear(); // Reload MenuItem attribute from editor assembly MonoAssembly* editorAssembly = MonoManager::instance().getAssembly(EDITOR_ASSEMBLY); mCustomInspectorAtribute = editorAssembly->getClass("BansheeEditor", "CustomInspector"); if (mCustomInspectorAtribute == nullptr) BS_EXCEPT(InvalidStateException, "Cannot find CustomInspector managed class."); MonoClass* inspectorClass = editorAssembly->getClass("BansheeEditor", "Inspector"); if (inspectorClass == nullptr) BS_EXCEPT(InvalidStateException, "Cannot find Inspector managed class."); MonoClass* inspectableFieldClass = editorAssembly->getClass("BansheeEditor", "InspectableField"); if (inspectableFieldClass == nullptr) BS_EXCEPT(InvalidStateException, "Cannot find InspectableField managed class."); mTypeField = mCustomInspectorAtribute->getField("type"); ScriptAssemblyManager& sam = ScriptAssemblyManager::instance(); Vector<String> scriptAssemblyNames = sam.getScriptAssemblies(); for (auto& assemblyName : scriptAssemblyNames) { MonoAssembly* assembly = MonoManager::instance().getAssembly(assemblyName); // Find new classes/structs with the custom inspector attribute const Vector<MonoClass*>& allClasses = assembly->getAllClasses(); for (auto curClass : allClasses) { MonoObject* attrib = curClass->getAttribute(mCustomInspectorAtribute); if (attrib == nullptr) continue; // Check if the attribute references a valid class MonoReflectionType* referencedReflType = nullptr; mTypeField->getValue(attrib, &referencedReflType); ::MonoClass* referencedMonoClass = MonoUtil::getClass(referencedReflType); MonoClass* referencedClass = MonoManager::instance().findClass(referencedMonoClass); if (referencedClass == nullptr) continue; if (curClass->isSubClassOf(inspectorClass)) { bool isValidInspectorType = referencedClass->isSubClassOf(ScriptResource::getMetaData()->scriptClass) || referencedClass->isSubClassOf(ScriptComponent::getMetaData()->scriptClass); if (!isValidInspectorType) continue; mInspectorTypes[referencedClass] = curClass; } else if (curClass->isSubClassOf(inspectableFieldClass)) { mInspectorTypes[referencedClass] = curClass; } } } }
void ScriptAssemblyManager::initializeBaseTypes() { // Get necessary classes for detecting needed class & field information MonoAssembly* corlib = MonoManager::instance().getAssembly("corlib"); if(corlib == nullptr) BS_EXCEPT(InvalidStateException, "corlib assembly is not loaded."); MonoAssembly* bansheeEngineAssembly = MonoManager::instance().getAssembly(ENGINE_ASSEMBLY); if(bansheeEngineAssembly == nullptr) BS_EXCEPT(InvalidStateException, String(ENGINE_ASSEMBLY) + " assembly is not loaded."); mSystemArrayClass = corlib->getClass("System", "Array"); if(mSystemArrayClass == nullptr) BS_EXCEPT(InvalidStateException, "Cannot find System.Array managed class."); mSystemGenericListClass = corlib->getClass("System.Collections.Generic", "List`1"); if(mSystemGenericListClass == nullptr) BS_EXCEPT(InvalidStateException, "Cannot find List<T> managed class."); mSystemGenericDictionaryClass = corlib->getClass("System.Collections.Generic", "Dictionary`2"); if(mSystemGenericDictionaryClass == nullptr) BS_EXCEPT(InvalidStateException, "Cannot find Dictionary<TKey, TValue> managed class."); mSystemTypeClass = corlib->getClass("System", "Type"); if (mSystemTypeClass == nullptr) BS_EXCEPT(InvalidStateException, "Cannot find Type managed class."); mSerializeObjectAttribute = bansheeEngineAssembly->getClass("BansheeEngine", "SerializeObject"); if(mSerializeObjectAttribute == nullptr) BS_EXCEPT(InvalidStateException, "Cannot find SerializableObject managed class."); mDontSerializeFieldAttribute = bansheeEngineAssembly->getClass("BansheeEngine", "DontSerializeField"); if(mDontSerializeFieldAttribute == nullptr) BS_EXCEPT(InvalidStateException, "Cannot find DontSerializeField managed class."); mRangeAttribute = bansheeEngineAssembly->getClass("BansheeEngine", "Range"); if (mRangeAttribute == nullptr) BS_EXCEPT(InvalidStateException, "Cannot find Range managed class."); mStepAttribute = bansheeEngineAssembly->getClass("BansheeEngine", "Step"); if (mStepAttribute == nullptr) BS_EXCEPT(InvalidStateException, "Cannot find Step managed class."); mComponentClass = bansheeEngineAssembly->getClass("BansheeEngine", "Component"); if(mComponentClass == nullptr) BS_EXCEPT(InvalidStateException, "Cannot find Component managed class."); mManagedComponentClass = bansheeEngineAssembly->getClass("BansheeEngine", "ManagedComponent"); if (mManagedComponentClass == nullptr) BS_EXCEPT(InvalidStateException, "Cannot find ManagedComponent managed class."); mMissingComponentClass = bansheeEngineAssembly->getClass("BansheeEngine", "MissingComponent"); if (mMissingComponentClass == nullptr) BS_EXCEPT(InvalidStateException, "Cannot find MissingComponent managed class."); mSceneObjectClass = bansheeEngineAssembly->getClass("BansheeEngine", "SceneObject"); if(mSceneObjectClass == nullptr) BS_EXCEPT(InvalidStateException, "Cannot find SceneObject managed class."); mSerializeFieldAttribute = bansheeEngineAssembly->getClass("BansheeEngine", "SerializeField"); if(mSerializeFieldAttribute == nullptr) BS_EXCEPT(InvalidStateException, "Cannot find SerializeField managed class."); mHideInInspectorAttribute = bansheeEngineAssembly->getClass("BansheeEngine", "HideInInspector"); if(mHideInInspectorAttribute == nullptr) BS_EXCEPT(InvalidStateException, "Cannot find HideInInspector managed class."); mShowInInspectorAttribute = bansheeEngineAssembly->getClass("BansheeEngine", "ShowInInspector"); if (mShowInInspectorAttribute == nullptr) BS_EXCEPT(InvalidStateException, "Cannot find ShowInInspector managed class."); mBaseTypesInitialized = true; }