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); } } } } }
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 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::loadAssemblyInfo(const String& assemblyName) { if(!mBaseTypesInitialized) initializeBaseTypes(); initializeBuiltinComponentInfos(); initializeBuiltinResourceInfos(); // Process all classes and fields UINT32 mUniqueTypeId = 1; MonoAssembly* curAssembly = MonoManager::instance().getAssembly(assemblyName); if(curAssembly == nullptr) return; SPtr<ManagedSerializableAssemblyInfo> assemblyInfo = bs_shared_ptr_new<ManagedSerializableAssemblyInfo>(); assemblyInfo->mName = assemblyName; mAssemblyInfos[assemblyName] = assemblyInfo; MonoClass* resourceClass = ScriptResource::getMetaData()->scriptClass; MonoClass* managedResourceClass = ScriptManagedResource::getMetaData()->scriptClass; // Populate class data const Vector<MonoClass*>& allClasses = curAssembly->getAllClasses(); for(auto& curClass : allClasses) { if ((curClass->isSubClassOf(mComponentClass) || curClass->isSubClassOf(resourceClass) || curClass->hasAttribute(mSerializeObjectAttribute)) && curClass != mComponentClass && curClass != resourceClass && curClass != mManagedComponentClass && curClass != managedResourceClass) { SPtr<ManagedSerializableTypeInfoObject> typeInfo = bs_shared_ptr_new<ManagedSerializableTypeInfoObject>(); typeInfo->mTypeNamespace = curClass->getNamespace(); typeInfo->mTypeName = curClass->getTypeName(); typeInfo->mTypeId = mUniqueTypeId++; MonoPrimitiveType monoPrimitiveType = MonoUtil::getPrimitiveType(curClass->_getInternalClass()); if(monoPrimitiveType == MonoPrimitiveType::ValueType) typeInfo->mValueType = true; else typeInfo->mValueType = false; SPtr<ManagedSerializableObjectInfo> objInfo = bs_shared_ptr_new<ManagedSerializableObjectInfo>(); objInfo->mTypeInfo = typeInfo; objInfo->mMonoClass = curClass; assemblyInfo->mTypeNameToId[objInfo->getFullTypeName()] = typeInfo->mTypeId; assemblyInfo->mObjectInfos[typeInfo->mTypeId] = objInfo; } } // Populate field & property data for(auto& curClassInfo : assemblyInfo->mObjectInfos) { SPtr<ManagedSerializableObjectInfo> objInfo = curClassInfo.second; UINT32 mUniqueFieldId = 1; const Vector<MonoField*>& fields = objInfo->mMonoClass->getAllFields(); for(auto& field : fields) { if(field->isStatic()) continue; SPtr<ManagedSerializableTypeInfo> typeInfo = getTypeInfo(field->getType()); if (typeInfo == nullptr) continue; SPtr<ManagedSerializableFieldInfo> fieldInfo = bs_shared_ptr_new<ManagedSerializableFieldInfo>(); fieldInfo->mFieldId = mUniqueFieldId++; fieldInfo->mName = field->getName(); fieldInfo->mMonoField = field; fieldInfo->mTypeInfo = typeInfo; fieldInfo->mParentTypeId = objInfo->mTypeInfo->mTypeId; MonoMemberVisibility visibility = field->getVisibility(); if (visibility == MonoMemberVisibility::Public) { if (!field->hasAttribute(mDontSerializeFieldAttribute)) fieldInfo->mFlags |= ScriptFieldFlag::Serializable; if (!field->hasAttribute(mHideInInspectorAttribute)) fieldInfo->mFlags |= ScriptFieldFlag::Inspectable; fieldInfo->mFlags |= ScriptFieldFlag::Animable; } else { if (field->hasAttribute(mSerializeFieldAttribute)) fieldInfo->mFlags |= ScriptFieldFlag::Serializable; if (field->hasAttribute(mShowInInspectorAttribute)) fieldInfo->mFlags |= ScriptFieldFlag::Inspectable; } if (field->hasAttribute(mRangeAttribute)) fieldInfo->mFlags |= ScriptFieldFlag::Range; if (field->hasAttribute(mStepAttribute)) fieldInfo->mFlags |= ScriptFieldFlag::Step; objInfo->mFieldNameToId[fieldInfo->mName] = fieldInfo->mFieldId; objInfo->mFields[fieldInfo->mFieldId] = fieldInfo; } const Vector<MonoProperty*>& properties = objInfo->mMonoClass->getAllProperties(); for (auto& property : properties) { SPtr<ManagedSerializableTypeInfo> typeInfo = getTypeInfo(property->getReturnType()); if (typeInfo == nullptr) continue; SPtr<ManagedSerializablePropertyInfo> propertyInfo = bs_shared_ptr_new<ManagedSerializablePropertyInfo>(); propertyInfo->mFieldId = mUniqueFieldId++; propertyInfo->mName = property->getName(); propertyInfo->mMonoProperty = property; propertyInfo->mTypeInfo = typeInfo; propertyInfo->mParentTypeId = objInfo->mTypeInfo->mTypeId; if (!property->isIndexed()) { MonoMemberVisibility visibility = property->getVisibility(); if (visibility == MonoMemberVisibility::Public) propertyInfo->mFlags |= ScriptFieldFlag::Animable; if (property->hasAttribute(mSerializeFieldAttribute)) propertyInfo->mFlags |= ScriptFieldFlag::Serializable; if (property->hasAttribute(mShowInInspectorAttribute)) propertyInfo->mFlags |= ScriptFieldFlag::Inspectable; } if (property->hasAttribute(mRangeAttribute)) propertyInfo->mFlags |= ScriptFieldFlag::Range; if (property->hasAttribute(mStepAttribute)) propertyInfo->mFlags |= ScriptFieldFlag::Step; objInfo->mFieldNameToId[propertyInfo->mName] = propertyInfo->mFieldId; objInfo->mFields[propertyInfo->mFieldId] = propertyInfo; } } // Form parent/child connections for(auto& curClass : assemblyInfo->mObjectInfos) { MonoClass* base = curClass.second->mMonoClass->getBaseClass(); while(base != nullptr) { SPtr<ManagedSerializableObjectInfo> baseObjInfo; if(getSerializableObjectInfo(base->getNamespace(), base->getTypeName(), baseObjInfo)) { curClass.second->mBaseClass = baseObjInfo; baseObjInfo->mDerivedClasses.push_back(curClass.second); break; } base = base->getBaseClass(); } } }