diff --git a/Source/Engine/Scripting/Enums.h b/Source/Engine/Scripting/Enums.h new file mode 100644 index 000000000..365e99200 --- /dev/null +++ b/Source/Engine/Scripting/Enums.h @@ -0,0 +1,65 @@ +// Copyright (c) 2012-2021 Wojciech Figat. All rights reserved. + +#pragma once + +#include "ScriptingType.h" +#include "Engine/Core/Types/String.h" + +// Utilities for using enums types (declared in scripting with API_ENUM). +template +class ScriptingEnum +{ +public: + // Gets the list with enum items (the last item Name is null) + static const ScriptingType::EnumItem* GetItems() + { + const ScriptingTypeHandle typeHandle = StaticType(); + if (typeHandle) + { + const ScriptingType& type = typeHandle.GetType(); + if (type.Type == ScriptingTypes::Enum) + return type.Enum.Items; + } + return nullptr; + } + + // Gets the name of the enum value or null if invalid + static const char* GetName(EnumType value) + { + if (const auto items = GetItems()) + { + for (int32 i = 0; items[i].Name; i++) + { + if (items[i].Value == (uint64)value) + return items[i].Name; + } + } + return nullptr; + } + + // Gets the name of the enum value or empty string if invalid + static String ToString(EnumType value) + { + return String(GetName(value)); + } + + // Gets the value of the enum based on the name. + static EnumType FromString(const StringAnsiView& name) + { + if (const auto items = GetItems()) + { + for (int32 i = 0; items[i].Name; i++) + { + if (name == items[i].Name) + return (EnumType)items[i].Value; + } + } + return (EnumType)0; + } + + // Gets the value of the enum based on the name. + static EnumType FromString(const StringView& name) + { + return FromString(StringAnsi(name)); + } +}; diff --git a/Source/Engine/Scripting/ScriptingType.h b/Source/Engine/Scripting/ScriptingType.h index 58713fcee..0f8afb09f 100644 --- a/Source/Engine/Scripting/ScriptingType.h +++ b/Source/Engine/Scripting/ScriptingType.h @@ -87,6 +87,9 @@ inline uint32 GetHash(const ScriptingTypeHandle& key) return (uint32)(uintptr)key.Module ^ key.TypeIndex; } +// C++ templated type accessor for scripting types. +template ScriptingTypeHandle StaticType(); + /// /// The scripting types. /// diff --git a/Source/Tools/Flax.Build/Bindings/BindingsGenerator.Cpp.cs b/Source/Tools/Flax.Build/Bindings/BindingsGenerator.Cpp.cs index c7f8a892f..89642692e 100644 --- a/Source/Tools/Flax.Build/Bindings/BindingsGenerator.Cpp.cs +++ b/Source/Tools/Flax.Build/Bindings/BindingsGenerator.Cpp.cs @@ -1979,6 +1979,8 @@ namespace Flax.Build.Bindings contents.Append($"StringAnsiView(\"{enumTypeNameManaged}\", {enumTypeNameManaged.Length}), "); contents.Append($"sizeof({enumTypeNameNative}), "); contents.Append($"{enumTypeNameInternal}Internal::Items);").AppendLine(); + + contents.AppendLine($"template<> {moduleInfo.Name.ToUpperInvariant()}_API ScriptingTypeHandle StaticType<{enumTypeNameNative}>() {{ return {enumTypeNameInternal}_TypeInitializer; }}"); } private static void GenerateCppInterface(BuildData buildData, StringBuilder contents, ModuleInfo moduleInfo, InterfaceInfo interfaceInfo)