List Serialization and Editor for Scripts #193

Merged
Pycorax merged 21 commits from SP3-6-ArraySerialization into main 2022-11-13 11:58:06 +08:00
3 changed files with 67 additions and 48 deletions
Showing only changes of commit dfc03839db - Show all commits

View File

@ -153,28 +153,28 @@ namespace SHADE
bool isHovered = false;
const bool MODIFIED_PRIMITIVE =
renderFieldInInspector<int , Int16 >(field, object, SHEditorUI::InputInt , &isHovered) ||
renderFieldInInspector<int , Int32 >(field, object, SHEditorUI::InputInt , &isHovered) ||
renderFieldInInspector<int , Int64 >(field, object, SHEditorUI::InputInt , &isHovered) ||
renderFieldInInspector<int , UInt16 >(field, object, SHEditorUI::InputInt , &isHovered) ||
renderFieldInInspector<int , UInt32 >(field, object, SHEditorUI::InputInt , &isHovered) ||
renderFieldInInspector<int , UInt64 >(field, object, SHEditorUI::InputInt , &isHovered) ||
renderFieldInInspector<int , Byte >(field, object, SHEditorUI::InputInt , &isHovered) ||
renderFieldInInspector<bool , bool >(field, object, SHEditorUI::InputCheckbox, &isHovered) ||
renderFieldInInspector<float , float >(field, object, SHEditorUI::InputFloat , &isHovered) ||
renderFieldInInspector<double , double >(field, object, SHEditorUI::InputDouble , &isHovered) ||
renderFieldInInspector<SHVec2 , Vector2 >(field, object, SHEditorUI::InputVec2 , &isHovered) ||
renderFieldInInspector<SHVec3 , Vector3 >(field, object, SHEditorUI::InputVec3 , &isHovered) ||
renderFieldInInspector<uint32_t , GameObject >(field, object, nullptr , &isHovered) ||
renderFieldInInspector<std::string, System::String^>(field, object, nullptr , &isHovered) ||
renderFieldInInspector<int , System::Enum >(field, object, nullptr , &isHovered);
renderSpecificField<int , Int16 >(field, object, SHEditorUI::InputInt , &isHovered) ||
renderSpecificField<int , Int32 >(field, object, SHEditorUI::InputInt , &isHovered) ||
renderSpecificField<int , Int64 >(field, object, SHEditorUI::InputInt , &isHovered) ||
renderSpecificField<int , UInt16 >(field, object, SHEditorUI::InputInt , &isHovered) ||
renderSpecificField<int , UInt32 >(field, object, SHEditorUI::InputInt , &isHovered) ||
renderSpecificField<int , UInt64 >(field, object, SHEditorUI::InputInt , &isHovered) ||
renderSpecificField<int , Byte >(field, object, SHEditorUI::InputInt , &isHovered) ||
renderSpecificField<bool , bool >(field, object, SHEditorUI::InputCheckbox, &isHovered) ||
renderSpecificField<float , float >(field, object, SHEditorUI::InputFloat , &isHovered) ||
renderSpecificField<double , double >(field, object, SHEditorUI::InputDouble , &isHovered) ||
renderSpecificField<SHVec2 , Vector2 >(field, object, SHEditorUI::InputVec2 , &isHovered) ||
renderSpecificField<SHVec3 , Vector3 >(field, object, SHEditorUI::InputVec3 , &isHovered) ||
renderSpecificField<uint32_t , GameObject >(field, object, nullptr , &isHovered) ||
renderSpecificField<std::string, System::String^>(field, object, nullptr , &isHovered) ||
renderSpecificField<int , System::Enum >(field, object, nullptr , &isHovered);
if (!MODIFIED_PRIMITIVE)
{
// Any List
if (field->FieldType->IsGenericType && field->FieldType->GetGenericTypeDefinition() == System::Collections::Generic::List<int>::typeid->GetGenericTypeDefinition())
{
System::Type^ listType = field->FieldType->GenericTypeArguments[0];
/* System::Type^ listType = field->FieldType->GenericTypeArguments[0];
RangeAttribute^ rangeAttrib = hasAttribute<RangeAttribute^>(field);
System::Collections::IList^ iList = safe_cast<System::Collections::IList^>(field->GetValue(object));
@ -193,7 +193,7 @@ namespace SHADE
SHEditorUI::SameLine();
SHEditorUI::Button("-");
}
SHEditorUI::Unindent();
SHEditorUI::Unindent();*/
}
else
{
@ -277,29 +277,29 @@ namespace SHADE
}
}
bool Editor::renderFieldInInspector(const std::string& fieldName, System::Object^% object, RangeAttribute^ rangeAttrib)
bool Editor::renderFieldEditor(const std::string& fieldName, System::Object^% object, RangeAttribute^ rangeAttrib)
{
const bool MODIFIED_PRIMITIVE =
renderFieldInInspector<int , Int16 >(fieldName, object, SHEditorUI::InputInt , nullptr, rangeAttrib) ||
renderFieldInInspector<int , Int32 >(fieldName, object, SHEditorUI::InputInt , nullptr, rangeAttrib) ||
renderFieldInInspector<int , Int64 >(fieldName, object, SHEditorUI::InputInt , nullptr, rangeAttrib) ||
renderFieldInInspector<int , UInt16 >(fieldName, object, SHEditorUI::InputInt , nullptr, rangeAttrib) ||
renderFieldInInspector<int , UInt32 >(fieldName, object, SHEditorUI::InputInt , nullptr, rangeAttrib) ||
renderFieldInInspector<int , UInt64 >(fieldName, object, SHEditorUI::InputInt , nullptr, rangeAttrib) ||
renderFieldInInspector<int , Byte >(fieldName, object, SHEditorUI::InputInt , nullptr, rangeAttrib) ||
renderFieldInInspector<bool , bool >(fieldName, object, SHEditorUI::InputCheckbox, nullptr, rangeAttrib) ||
renderFieldInInspector<float , float >(fieldName, object, SHEditorUI::InputFloat , nullptr, rangeAttrib) ||
renderFieldInInspector<double , double >(fieldName, object, SHEditorUI::InputDouble , nullptr, rangeAttrib) ||
renderFieldInInspector<SHVec2 , Vector2 >(fieldName, object, SHEditorUI::InputVec2 , nullptr, rangeAttrib) ||
renderFieldInInspector<SHVec3 , Vector3 >(fieldName, object, SHEditorUI::InputVec3 , nullptr, rangeAttrib) ||
renderFieldInInspector<uint32_t , GameObject >(fieldName, object, nullptr , nullptr, rangeAttrib) ||
renderFieldInInspector<std::string, System::String^>(fieldName, object, nullptr , nullptr, rangeAttrib) ||
renderFieldInInspector<int , System::Enum >(fieldName, object, nullptr , nullptr, rangeAttrib);
renderFieldEditor<int , Int16 >(fieldName, object, SHEditorUI::InputInt , nullptr, rangeAttrib) ||
renderFieldEditor<int , Int32 >(fieldName, object, SHEditorUI::InputInt , nullptr, rangeAttrib) ||
renderFieldEditor<int , Int64 >(fieldName, object, SHEditorUI::InputInt , nullptr, rangeAttrib) ||
renderFieldEditor<int , UInt16 >(fieldName, object, SHEditorUI::InputInt , nullptr, rangeAttrib) ||
renderFieldEditor<int , UInt32 >(fieldName, object, SHEditorUI::InputInt , nullptr, rangeAttrib) ||
renderFieldEditor<int , UInt64 >(fieldName, object, SHEditorUI::InputInt , nullptr, rangeAttrib) ||
renderFieldEditor<int , Byte >(fieldName, object, SHEditorUI::InputInt , nullptr, rangeAttrib) ||
renderFieldEditor<bool , bool >(fieldName, object, SHEditorUI::InputCheckbox, nullptr, rangeAttrib) ||
renderFieldEditor<float , float >(fieldName, object, SHEditorUI::InputFloat , nullptr, rangeAttrib) ||
renderFieldEditor<double , double >(fieldName, object, SHEditorUI::InputDouble , nullptr, rangeAttrib) ||
renderFieldEditor<SHVec2 , Vector2 >(fieldName, object, SHEditorUI::InputVec2 , nullptr, rangeAttrib) ||
renderFieldEditor<SHVec3 , Vector3 >(fieldName, object, SHEditorUI::InputVec3 , nullptr, rangeAttrib) ||
renderFieldEditor<uint32_t , GameObject >(fieldName, object, nullptr , nullptr, rangeAttrib) ||
renderFieldEditor<std::string, System::String^>(fieldName, object, nullptr , nullptr, rangeAttrib) ||
renderFieldEditor<int , System::Enum >(fieldName, object, nullptr , nullptr, rangeAttrib);
return MODIFIED_PRIMITIVE;
}
bool Editor::renderEnumFieldInInspector(const std::string& fieldName, System::Object^% object, bool* isHovered)
bool Editor::renderEnumEditor(const std::string& fieldName, System::Object^% object, bool* isHovered)
{
// Get all the names of the enums
const array<String^>^ ENUM_NAMES = object->GetType()->GetEnumNames();

View File

@ -24,7 +24,7 @@ of DigiPen Institute of Technology is prohibited.
namespace SHADE
{
template<typename NativeType, typename ManagedType>
bool Editor::renderFieldInInspector(System::Reflection::FieldInfo^ fieldInfo, System::Object^ object, EditorFieldFunc<NativeType> fieldEditor, bool* isHovered)
bool Editor::renderSpecificField(System::Reflection::FieldInfo^ fieldInfo, System::Object^ object, EditorFieldFunc<NativeType> fieldEditor, bool* isHovered)
{
if constexpr (std::is_same_v<ManagedType, System::Enum>)
{
@ -33,7 +33,7 @@ namespace SHADE
System::Object^ enumObj = fieldInfo->GetValue(object);
int oldVal = safe_cast<int>(enumObj);
int val = oldVal;
if (renderEnumFieldInInspector
if (renderEnumEditor
(
Convert::ToNative(fieldInfo->Name),
enumObj,
@ -59,7 +59,7 @@ namespace SHADE
ManagedType oldVal = safe_cast<ManagedType>(fieldInfo->GetValue(object));
ManagedType val = oldVal;
if (renderFieldInInspector<NativeType, ManagedType>
if (renderFieldEditorInternal<NativeType, ManagedType>
(
Convert::ToNative(fieldInfo->Name),
&val,
@ -80,14 +80,14 @@ namespace SHADE
}
template<typename NativeType, typename ManagedType>
bool Editor::renderFieldInInspector(const std::string& fieldName, System::Object^% object, EditorFieldFunc<NativeType> fieldEditor, bool* isHovered, RangeAttribute^ rangeAttrib)
bool Editor::renderFieldEditor(const std::string& fieldName, System::Object^% object, EditorFieldFunc<NativeType> fieldEditor, bool* isHovered, RangeAttribute^ rangeAttrib)
{
if constexpr (std::is_same_v<ManagedType, System::Enum>)
{
if (object->GetType()->IsSubclassOf(Enum::typeid))
{
int managedVal = safe_cast<int>(object);
if (renderFieldInInspector<int, int>(fieldName, &managedVal, fieldEditor, isHovered, rangeAttrib))
if (renderFieldEditorInternal<int, int>(fieldName, &managedVal, fieldEditor, isHovered, rangeAttrib))
{
object = managedVal;
}
@ -100,7 +100,7 @@ namespace SHADE
{
ManagedType managedVal = safe_cast<ManagedType>(object);
cli::interior_ptr<ManagedType> managedValPtr = &managedVal;
if (renderFieldInInspector<NativeType, ManagedType>(fieldName, managedValPtr, fieldEditor, isHovered, rangeAttrib))
if (renderFieldEditorInternal<NativeType, ManagedType>(fieldName, managedValPtr, fieldEditor, isHovered, rangeAttrib))
{
object = managedVal;
return true;
@ -114,7 +114,7 @@ namespace SHADE
template<typename NativeType, typename ManagedType>
bool Editor::renderFieldInInspector(const std::string& fieldName, interior_ptr<ManagedType> managedValPtr, EditorFieldFunc<NativeType> fieldEditor, bool* isHovered, RangeAttribute^ rangeAttrib)
bool Editor::renderFieldEditorInternal(const std::string& fieldName, interior_ptr<ManagedType> managedValPtr, EditorFieldFunc<NativeType> fieldEditor, bool* isHovered, RangeAttribute^ rangeAttrib)
{
// Retrieve the native version of the object
NativeType val;
@ -167,7 +167,7 @@ namespace SHADE
return false;
}
template<>
bool Editor::renderFieldInInspector<std::string, System::String^>(const std::string& fieldName, interior_ptr<System::String^> managedValPtr, EditorFieldFunc<std::string>, bool* isHovered, RangeAttribute^)
bool Editor::renderFieldEditorInternal<std::string, System::String^>(const std::string& fieldName, interior_ptr<System::String^> managedValPtr, EditorFieldFunc<std::string>, bool* isHovered, RangeAttribute^)
{
// Prevent issues where String^ is null due to being empty
if (*managedValPtr == nullptr)
@ -184,7 +184,7 @@ namespace SHADE
return false;
}
template<>
bool Editor::renderFieldInInspector<uint32_t, GameObject>(const std::string& fieldName, interior_ptr<GameObject> managedValPtr, EditorFieldFunc<uint32_t>, bool* isHovered, RangeAttribute^)
bool Editor::renderFieldEditorInternal<uint32_t, GameObject>(const std::string& fieldName, interior_ptr<GameObject> managedValPtr, EditorFieldFunc<uint32_t>, bool* isHovered, RangeAttribute^)
{
uint32_t entityId = managedValPtr->GetEntity();
if (SHEditorUI::InputGameObjectField(fieldName, entityId, isHovered, !(*managedValPtr)))

View File

@ -90,8 +90,8 @@ namespace SHADE
/// The object that contains the data of the field to render.
/// </param>
static void renderFieldInInspector(System::Reflection::FieldInfo^ field, System::Object^ object);
static bool renderFieldInInspector(const std::string& fieldName, System::Object^% object, RangeAttribute^ rangeAttrib);
static bool renderEnumFieldInInspector(const std::string& fieldName, System::Object^% object, bool* isHovered);
static bool renderFieldEditor(const std::string& fieldName, System::Object^% object, RangeAttribute^ rangeAttrib);
static bool renderEnumEditor(const std::string& fieldName, System::Object^% object, bool* isHovered);
/// <summary>
/// Checks if the specified field is of the specified native and managed type
/// equivalent and renders a ImGui field editor based on the specified field
@ -107,7 +107,7 @@ namespace SHADE
/// </param>
/// <returns>True if the field is modified.</returns>
template<typename NativeType, typename ManagedType>
static bool renderFieldInInspector(System::Reflection::FieldInfo^ fieldInfo, System::Object^ object, EditorFieldFunc<NativeType> fieldEditor, bool* isHovered);
static bool renderSpecificField(System::Reflection::FieldInfo^ fieldInfo, System::Object^ object, EditorFieldFunc<NativeType> fieldEditor, bool* isHovered);
/// <summary>
/// Renders a ImGui field editor based on the type of parameters specified.
/// </summary>
@ -127,9 +127,28 @@ namespace SHADE
/// </param>
/// <returns>True if the field is modified.</returns>
template<typename NativeType, typename ManagedType>
static bool renderFieldInInspector(const std::string& fieldName, interior_ptr<ManagedType> managedValPtr, EditorFieldFunc<NativeType> fieldEditor, bool* isHovered, RangeAttribute^ rangeAttrib);
static bool renderFieldEditorInternal(const std::string& fieldName, interior_ptr<ManagedType> managedValPtr, EditorFieldFunc<NativeType> fieldEditor, bool* isHovered, RangeAttribute^ rangeAttrib);
/// <summary>
/// Renders a ImGui field editor based on the type of parameters specified.
/// </summary>
/// <typeparam name="NativeType">Native type of the field.</typeparam>
/// <typeparam name="ManagedType">Managed type of the field.</typeparam>
/// <param name="fieldName">Label to use for the field editor.</param>
/// <param name="managedVal">
/// Tracking reference for the managed variable to modify.
/// </param>
/// <param name="fieldEditor">ImGui field editor function to use.</param>
/// <param name="isHovered">
/// Pointer to a bool that stores if the field editor was hovered over.
/// </param>
/// <param name="rangeAttrib">
/// If provided and the type supports it, the field will be rendered with a
/// slider instead.
/// </param>
/// <returns>True if the field is modified.</returns>
template<typename NativeType, typename ManagedType>
static bool renderFieldInInspector(const std::string& fieldName, System::Object^% object, EditorFieldFunc<NativeType> fieldEditor, bool* isHovered, RangeAttribute^ rangeAttrib);
static bool renderFieldEditor(const std::string& fieldName, System::Object^% object, EditorFieldFunc<NativeType> fieldEditor, bool* isHovered, RangeAttribute^ rangeAttrib);
/// <summary>
/// Renders a context menu when right clicked for the scripts
/// </summary>