Converted macros for script field inspectors to use templates
This commit is contained in:
parent
e8d2179d76
commit
bdc7297937
|
@ -266,10 +266,10 @@ namespace SHADE
|
|||
static const std::vector<std::string> COMPONENT_LABELS = { "X", "Y" };
|
||||
return SHEditorWidgets::DragN<float, 2>(label, COMPONENT_LABELS, { &value.x, &value.y }, 0.1f, "%.3f", float{}, float{}, 0, isHovered);
|
||||
}
|
||||
bool SHEditorUI::InputVec3(const std::string& label, SHVec3& value, bool* isHovered, float speed)
|
||||
bool SHEditorUI::InputVec3(const std::string& label, SHVec3& value, bool* isHovered)
|
||||
{
|
||||
static const std::vector<std::string> COMPONENT_LABELS = { "X", "Y", "Z"};
|
||||
return SHEditorWidgets::DragN<float, 3>(label, COMPONENT_LABELS, { &value.x, &value.y, &value.z }, speed, "%.3f", float{}, float{}, 0, isHovered);
|
||||
return SHEditorWidgets::DragN<float, 3>(label, COMPONENT_LABELS, { &value.x, &value.y, &value.z }, 0.1f, "%.3f", float{}, float{}, 0, isHovered);
|
||||
}
|
||||
|
||||
bool SHEditorUI::InputTextField(const std::string& label, std::string& value, bool* isHovered)
|
||||
|
|
|
@ -296,7 +296,7 @@ namespace SHADE
|
|||
/// <param name="value">Reference to the variable to store the result.</param>
|
||||
/// <param name="isHovered>If set, stores the hover state of this widget.</param>
|
||||
/// <returns>True if the value was changed.</returns>
|
||||
static bool InputVec3(const std::string& label, SHVec3& value, bool* isHovered = nullptr, float speed = 0.1f);
|
||||
static bool InputVec3(const std::string& label, SHVec3& value, bool* isHovered = nullptr);
|
||||
/// <summary>
|
||||
/// Creates a text field widget for string input.
|
||||
/// <br/>
|
||||
|
|
|
@ -31,98 +31,13 @@ of DigiPen Institute of Technology is prohibited.
|
|||
#include "Editor/Command/SHCommand.hpp"
|
||||
#include "TooltipAttribute.hxx"
|
||||
#include "RangeAttribute.hxx"
|
||||
#include "Math/Vector2.hxx"
|
||||
#include "Math/Vector3.hxx"
|
||||
|
||||
// Using Directives
|
||||
using namespace System;
|
||||
using namespace System::Collections::Generic;
|
||||
|
||||
/*-------------------------------------------------------------------------------------*/
|
||||
/* Macro Functions */
|
||||
/*-------------------------------------------------------------------------------------*/
|
||||
/// <summary>
|
||||
/// Macro expansion that is used in renderFieldInInspector() to check the type of a field
|
||||
/// named "field" against the specified type and if it matches, retrieves the value of
|
||||
/// that field from an object named "object" and pass it into the specified SHEditorUI::
|
||||
/// function named "FUNC" by casting it into the NATIVE_TYPE specified.
|
||||
/// <br/>
|
||||
/// This only works for primitive types that have the same types for managed and native.
|
||||
/// </summary>
|
||||
/// <param name="MANAGED_TYPE">The managed type of the object to edit.</param>
|
||||
/// <param name="NATIVE_TYPE">The native type of the object to edit.</param>
|
||||
/// <param name="FUNC">The SHEditorUI:: function to use for editing.</param>
|
||||
#define RENDER_FIELD(MANAGED_TYPE, NATIVE_TYPE, FUNC) \
|
||||
(field->FieldType == MANAGED_TYPE::typeid) \
|
||||
{ \
|
||||
NATIVE_TYPE val = safe_cast<NATIVE_TYPE>(field->GetValue(object)); \
|
||||
NATIVE_TYPE oldVal = val; \
|
||||
if (SHEditorUI::FUNC(Convert::ToNative(field->Name), val, &isHovered))\
|
||||
{ \
|
||||
field->SetValue(object, val); \
|
||||
registerUndoAction(object, field, val, oldVal); \
|
||||
} \
|
||||
} \
|
||||
/// <summary>
|
||||
/// Alternative to RENDER_FIELD that checks for RangeAttribute and switches to a slider
|
||||
/// instead.
|
||||
/// </summary>
|
||||
/// <param name="MANAGED_TYPE">The managed type of the object to edit.</param>
|
||||
/// <param name="NATIVE_TYPE">The native type of the object to edit.</param>
|
||||
/// <param name="FUNC">The SHEditorUI:: function to use for editing.</param>
|
||||
#define RENDER_FIELD_RANGE(MANAGED_TYPE, NATIVE_TYPE, FUNC) \
|
||||
(field->FieldType == MANAGED_TYPE::typeid) \
|
||||
{ \
|
||||
NATIVE_TYPE val = safe_cast<NATIVE_TYPE>(field->GetValue(object)); \
|
||||
NATIVE_TYPE oldVal = val; \
|
||||
\
|
||||
RangeAttribute^ rangeAttrib = hasAttribute<RangeAttribute^>(field);\
|
||||
const std::string FIELD_NAME = Convert::ToNative(field->Name); \
|
||||
bool changed = false; \
|
||||
if (rangeAttrib) \
|
||||
{ \
|
||||
changed = SHEditorUI::InputSlider \
|
||||
( \
|
||||
FIELD_NAME, \
|
||||
static_cast<NATIVE_TYPE>(rangeAttrib->Min), \
|
||||
static_cast<NATIVE_TYPE>(rangeAttrib->Max), \
|
||||
val, &isHovered \
|
||||
); \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
changed = SHEditorUI::FUNC(FIELD_NAME, val, &isHovered); \
|
||||
} \
|
||||
\
|
||||
if (changed) \
|
||||
{ \
|
||||
field->SetValue(object, val); \
|
||||
registerUndoAction(object, field, val, oldVal); \
|
||||
} \
|
||||
} \
|
||||
/// <summary>
|
||||
/// Macro expansion that is used in renderFieldInInspector() to check the type of a field
|
||||
/// named "field" against the specified type and if it matches, retrieves the value of
|
||||
/// that field from an object named "object" and pass it into the specified SHEditorUI::
|
||||
/// function named "FUNC" by casting it into the NATIVE_TYPE specified.
|
||||
/// <br/>
|
||||
/// This only works for types that have an implementation of Convert::ToNative and
|
||||
/// Convert::ToCLI.
|
||||
/// </summary>
|
||||
/// <param name="MANAGED_TYPE">The managed type of the object to edit.</param>
|
||||
/// <param name="NATIVE_TYPE">The native type of the object to edit.</param>
|
||||
/// <param name="FUNC">The SHEditorUI:: function to use for editing.</param>
|
||||
#define RENDER_FIELD_CASTED(MANAGED_TYPE, NATIVE_TYPE, FUNC) \
|
||||
(field->FieldType == MANAGED_TYPE::typeid) \
|
||||
{ \
|
||||
NATIVE_TYPE val = Convert::ToNative(safe_cast<MANAGED_TYPE>(field->GetValue(object))); \
|
||||
NATIVE_TYPE oldVal = val; \
|
||||
\
|
||||
if (SHEditorUI::FUNC(Convert::ToNative(field->Name), val, &isHovered)) \
|
||||
{ \
|
||||
field->SetValue(object, Convert::ToCLI(val)); \
|
||||
registerUndoAction(object, field, Convert::ToCLI(val), Convert::ToCLI(oldVal)); \
|
||||
} \
|
||||
} \
|
||||
|
||||
/*-------------------------------------------------------------------------------------*/
|
||||
/* Function Definitions */
|
||||
/*-------------------------------------------------------------------------------------*/
|
||||
|
@ -238,22 +153,28 @@ namespace SHADE
|
|||
{
|
||||
bool isHovered = false;
|
||||
|
||||
if RENDER_FIELD_RANGE (Int16, int, InputInt)
|
||||
else if RENDER_FIELD_RANGE (Int32, int, InputInt)
|
||||
else if RENDER_FIELD_RANGE (Int64, int, InputInt)
|
||||
else if RENDER_FIELD_RANGE (UInt16, unsigned int, InputUnsignedInt)
|
||||
else if RENDER_FIELD_RANGE (UInt32, unsigned int, InputUnsignedInt)
|
||||
else if RENDER_FIELD_RANGE (UInt64, unsigned int, InputUnsignedInt)
|
||||
else if RENDER_FIELD_RANGE (Byte, int, InputInt)
|
||||
else if RENDER_FIELD (bool, bool, InputCheckbox)
|
||||
else if RENDER_FIELD_RANGE (float, float, InputFloat)
|
||||
else if RENDER_FIELD_RANGE (double, double, InputDouble)
|
||||
else if (field->FieldType->IsSubclassOf(Enum::typeid))
|
||||
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);
|
||||
|
||||
if (!MODIFIED_PRIMITIVE)
|
||||
{
|
||||
if (field->FieldType->IsSubclassOf(Enum::typeid))
|
||||
{
|
||||
// Get all the names of the enums
|
||||
const array<String^>^ ENUM_NAMES = field->FieldType->GetEnumNames();
|
||||
std::vector<std::string> nativeEnumNames;
|
||||
for each (String^ str in ENUM_NAMES)
|
||||
for each (String ^ str in ENUM_NAMES)
|
||||
{
|
||||
nativeEnumNames.emplace_back(Convert::ToNative(str));
|
||||
}
|
||||
|
@ -266,8 +187,6 @@ namespace SHADE
|
|||
registerUndoAction(object, field, val, oldVal);
|
||||
}
|
||||
}
|
||||
else if RENDER_FIELD_CASTED(Vector2, SHVec2, InputVec2)
|
||||
else if RENDER_FIELD_CASTED(Vector3, SHVec3, InputVec3)
|
||||
else if (field->FieldType == String::typeid)
|
||||
{
|
||||
// Prevent issues where String^ is null due to being empty
|
||||
|
@ -315,7 +234,7 @@ namespace SHADE
|
|||
|
||||
SHEditorUI::Indent();
|
||||
int i = 0;
|
||||
for each (System::Object^ obj in listEnummerable)
|
||||
for each (System::Object ^ obj in listEnummerable)
|
||||
{
|
||||
int val = safe_cast<int>(obj);
|
||||
SHEditorUI::InputInt(std::to_string(i), val, &isHovered);
|
||||
|
@ -395,6 +314,7 @@ namespace SHADE
|
|||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check if the field has a specific attribute
|
||||
TooltipAttribute^ toolTip = hasAttribute<TooltipAttribute^>(field);
|
||||
|
|
|
@ -0,0 +1,109 @@
|
|||
/************************************************************************************//*!
|
||||
\file Editor.h++
|
||||
\author Tng Kah Wei, kahwei.tng, 390009620
|
||||
\par email: kahwei.tng\@digipen.edu
|
||||
\date Nov 10, 2022
|
||||
\brief Contains the definition of templated functions for the managed Editor
|
||||
static class.
|
||||
|
||||
Note: This file is written in C++17/CLI.
|
||||
|
||||
Copyright (C) 2022 DigiPen Institute of Technology.
|
||||
Reproduction or disclosure of this file or its contents without the prior written consent
|
||||
of DigiPen Institute of Technology is prohibited.
|
||||
*//*************************************************************************************/
|
||||
#pragma once
|
||||
|
||||
// Primary Include
|
||||
#include "Editor.hxx"
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
template<typename NativeType, typename ManagedType>
|
||||
bool Editor::renderFieldInInspector(System::Reflection::FieldInfo^ fieldInfo, System::Object^ object, EditorFieldFunc<NativeType> fieldEditor, bool* isHovered)
|
||||
{
|
||||
if (fieldInfo->FieldType == ManagedType::typeid)
|
||||
{
|
||||
RangeAttribute^ rangeAttrib;
|
||||
if constexpr (std::is_arithmetic_v<NativeType> && !std::is_same_v<NativeType, bool>)
|
||||
{
|
||||
rangeAttrib = hasAttribute<RangeAttribute^>(fieldInfo);
|
||||
}
|
||||
|
||||
ManagedType val = safe_cast<ManagedType>(fieldInfo->GetValue(object));
|
||||
if (renderFieldInInspector<NativeType, ManagedType>
|
||||
(
|
||||
Convert::ToNative(fieldInfo->Name),
|
||||
val,
|
||||
fieldEditor,
|
||||
isHovered,
|
||||
rangeAttrib
|
||||
))
|
||||
{
|
||||
fieldInfo->SetValue(object, val);
|
||||
// TODO: Register undo
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
template<typename NativeType, typename ManagedType>
|
||||
bool Editor::renderFieldInInspector(const std::string& fieldName, ManagedType% managedVal, EditorFieldFunc<NativeType> fieldEditor, bool* isHovered, RangeAttribute^ rangeAttrib)
|
||||
{
|
||||
// Retrieve the native version of the object
|
||||
NativeType val;
|
||||
if constexpr (IsPrimitiveTypeMatches_V<NativeType>)
|
||||
{
|
||||
val = safe_cast<NativeType>(managedVal);
|
||||
}
|
||||
else
|
||||
{
|
||||
val = Convert::ToNative(managedVal);
|
||||
}
|
||||
|
||||
// Throw into the SHEditorUI function
|
||||
NativeType oldVal = val;
|
||||
bool changed = false;
|
||||
if (rangeAttrib)
|
||||
{
|
||||
// Do not allow bools for Sliders just in case
|
||||
if constexpr (std::is_arithmetic_v<NativeType> && !std::is_same_v<NativeType, bool>)
|
||||
{
|
||||
changed = SHEditorUI::InputSlider
|
||||
(
|
||||
fieldName,
|
||||
static_cast<NativeType>(rangeAttrib->Min),
|
||||
static_cast<NativeType>(rangeAttrib->Max),
|
||||
val, isHovered
|
||||
);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
changed = fieldEditor(fieldName, val, isHovered);
|
||||
}
|
||||
|
||||
if (changed)
|
||||
{
|
||||
if constexpr (IsPrimitiveTypeMatches_V<NativeType>)
|
||||
{
|
||||
//field->SetValue(object, val);
|
||||
managedVal = val;
|
||||
//registerUndoAction(object, field, val, oldVal);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
managedVal = Convert::ToCLI(val);
|
||||
//registerUndoAction(object, field, Convert::ToCLI(val), Convert::ToCLI(oldVal));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
|
@ -17,9 +17,14 @@ of DigiPen Institute of Technology is prohibited.
|
|||
#include "Engine/Entity.hxx"
|
||||
#include "Scripts/Script.hxx"
|
||||
#include "UndoRedoStack.hxx"
|
||||
#include "RangeAttribute.hxx"
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
|
||||
template<typename NativeType>
|
||||
using EditorFieldFunc = bool(*)(const std::string& label, NativeType& val, bool* isHovered);
|
||||
|
||||
/// <summary>
|
||||
/// Static class for Editor-related functions
|
||||
/// </summary>
|
||||
|
@ -91,8 +96,59 @@ namespace SHADE
|
|||
/// <param name="entity">The Entity to render the Scripts of.</param>
|
||||
/// <param name="script">The Script to render the inspector for.</param>
|
||||
static void renderScriptContextMenu(Entity entity, Script^ script);
|
||||
/// <summary>
|
||||
/// Adds changes to a variable as an undo-able/redo-able action on the Undo-Redo
|
||||
/// stack.
|
||||
/// </summary>
|
||||
/// <param name="object">The object that changes are applied to.</param>
|
||||
/// <param name="field">The field that was changed.</param>
|
||||
/// <param name="newData">New data to set.</param>
|
||||
/// <param name="oldData">Data that was overriden.</param>
|
||||
static void registerUndoAction(System::Object^ object, System::Reflection::FieldInfo^ field, System::Object^ newData, System::Object^ oldData);
|
||||
/// <summary>
|
||||
/// Checks if a specific field has the specified attribute
|
||||
/// </summary>
|
||||
/// <typeparam name="Attribute">Type of Attribute to check for.</typeparam>
|
||||
/// <param name="field">The field to check.</param>
|
||||
/// <returns>The attribute to check for if it exists. Null otherwise.</returns>
|
||||
generic<typename Attribute> where Attribute : System::Attribute
|
||||
static Attribute hasAttribute(System::Reflection::FieldInfo^ field);
|
||||
/// <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
|
||||
/// editor function. Also handles fields that contain a RangeAttribute.
|
||||
/// </summary>
|
||||
/// <typeparam name="NativeType">Native type of the field.</typeparam>
|
||||
/// <typeparam name="ManagedType">Managed type of the field.</typeparam>
|
||||
/// <param name="fieldInfo">Describes the field to modify.</param>
|
||||
/// <param name="object">Object to modify that has the specified field.</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>
|
||||
/// <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);
|
||||
/// <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, ManagedType% managedVal, EditorFieldFunc<NativeType> fieldEditor, bool* isHovered, RangeAttribute^ rangeAttrib);
|
||||
};
|
||||
}
|
||||
#include "Editor.h++"
|
||||
|
|
|
@ -152,6 +152,40 @@ namespace SHADE
|
|||
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Checks if the specified type is matching between native C++ and the managed type.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">Type to check.</typeparam>
|
||||
template<typename T>
|
||||
struct IsPrimitiveTypeMatches : public std::integral_constant
|
||||
<
|
||||
bool,
|
||||
std::is_same_v<System::Int16 , typename std::remove_cv_t<T>> ||
|
||||
std::is_same_v<System::Int32 , typename std::remove_cv_t<T>> ||
|
||||
std::is_same_v<System::Int64 , typename std::remove_cv_t<T>> ||
|
||||
std::is_same_v<System::UInt16, typename std::remove_cv_t<T>> ||
|
||||
std::is_same_v<System::UInt32, typename std::remove_cv_t<T>> ||
|
||||
std::is_same_v<System::UInt64, typename std::remove_cv_t<T>> ||
|
||||
std::is_same_v<System::Byte , typename std::remove_cv_t<T>> ||
|
||||
std::is_same_v<bool , typename std::remove_cv_t<T>> ||
|
||||
std::is_same_v<double , typename std::remove_cv_t<T>> ||
|
||||
std::is_same_v<float , typename std::remove_cv_t<T>> ||
|
||||
std::is_same_v<int8_t , typename std::remove_cv_t<T>> ||
|
||||
std::is_same_v<int16_t , typename std::remove_cv_t<T>> ||
|
||||
std::is_same_v<int32_t , typename std::remove_cv_t<T>> ||
|
||||
std::is_same_v<int64_t , typename std::remove_cv_t<T>> ||
|
||||
std::is_same_v<uint16_t , typename std::remove_cv_t<T>> ||
|
||||
std::is_same_v<uint32_t , typename std::remove_cv_t<T>> ||
|
||||
std::is_same_v<uint64_t , typename std::remove_cv_t<T>>
|
||||
>
|
||||
{};
|
||||
/// <summary>
|
||||
/// Short hand for IsPrimitiveTypeMatches::value
|
||||
/// </summary>
|
||||
/// <typeparam name="T">Type to check.</typeparam>
|
||||
template<typename T>
|
||||
inline constexpr bool IsPrimitiveTypeMatches_V = IsPrimitiveTypeMatches<T>::value;
|
||||
|
||||
/// <summary>
|
||||
/// Type Transformer for managed types to native types.
|
||||
/// </summary>
|
||||
|
@ -163,6 +197,7 @@ namespace SHADE
|
|||
{
|
||||
public:
|
||||
using Value = void;
|
||||
static bool IsDefined() { return is_same_v<ManagedType, Value>; }
|
||||
};
|
||||
template<> struct ToNativeType<System::Int16> { using Value = int16_t; };
|
||||
template<> struct ToNativeType<System::Int32> { using Value = int32_t; };
|
||||
|
@ -195,17 +230,18 @@ namespace SHADE
|
|||
{
|
||||
public:
|
||||
using Value = void;
|
||||
static bool IsDefined() { return is_same_v<NativeType, Value>; }
|
||||
};
|
||||
template<> struct ToManagedType<int8_t> { using Value = System::Byte; };
|
||||
template<> struct ToManagedType<int16_t> { using Value = System::Int16; };
|
||||
template<> struct ToManagedType<int32_t> { using Value = System::Int32; };
|
||||
template<> struct ToManagedType<int64_t> { using Value = System::Int64; };
|
||||
template<> struct ToManagedType<int8_t > { using Value = System::Byte; };
|
||||
template<> struct ToManagedType<int16_t > { using Value = System::Int16; };
|
||||
template<> struct ToManagedType<int32_t > { using Value = System::Int32; };
|
||||
template<> struct ToManagedType<int64_t > { using Value = System::Int64; };
|
||||
template<> struct ToManagedType<uint16_t> { using Value = System::UInt16; };
|
||||
template<> struct ToManagedType<uint32_t> { using Value = System::UInt32; };
|
||||
template<> struct ToManagedType<uint64_t> { using Value = System::UInt64; };
|
||||
template<> struct ToManagedType<bool> { using Value = bool; };
|
||||
template<> struct ToManagedType<double> { using Value = double; };
|
||||
template<> struct ToManagedType<float> { using Value = float; };
|
||||
template<> struct ToManagedType<bool > { using Value = bool; };
|
||||
template<> struct ToManagedType<double > { using Value = double; };
|
||||
template<> struct ToManagedType<float > { using Value = float; };
|
||||
|
||||
/// <summary>
|
||||
/// Alias for ToManagedType::Value
|
||||
|
|
Loading…
Reference in New Issue