1f9b284de2
Signed-off-by: Esteban Papp <81431996+amznestebanpapp@users.noreply.github.com> # Conflicts: # Code/Editor/Plugins/ComponentEntityEditorPlugin/ComponentEntityEditorPlugin_precompiled.h # Code/Editor/Plugins/EditorCommon/EditorCommon_precompiled.h # Code/Editor/Plugins/EditorCommon/stdafx.cpp # Code/Editor/Plugins/FFMPEGPlugin/FFMPEGPlugin_precompiled.h # Code/Editor/Plugins/PerforcePlugin/PerforcePlugin_precompiled.h # Code/Editor/Plugins/ProjectSettingsTool/ProjectSettingsTool_precompiled.h # Code/Framework/AzToolsFramework/AzToolsFramework/AzToolsFramework_precompiled.h # Code/Tools/AssetProcessor/native/precompiled.h # Code/Tools/Standalone/StandaloneTools_precompiled.h # Gems/AssetMemoryAnalyzer/Code/Source/AssetMemoryAnalyzer_precompiled.h # Gems/Atom/Asset/ImageProcessingAtom/Code/Source/ImageProcessing_precompiled.h # Gems/Atom/RHI/DX12/Code/Source/RHI/Atom_RHI_DX12_precompiled.h # Gems/Atom/RHI/Metal/Code/Include/Platform/Mac/Atom_RHI_Metal_precompiled_Platform.h # Gems/Atom/RHI/Metal/Code/Include/Platform/iOS/Atom_RHI_Metal_precompiled_Platform.h # Gems/Atom/RHI/Metal/Code/Source/Atom_RHI_Metal_precompiled.h # Gems/Atom/RHI/Metal/Code/atom_rhi_metal_common_files.cmake # Gems/Atom/RHI/Null/Code/Source/Atom_RHI_Null_precompiled.h # Gems/Atom/RHI/Null/Code/atom_rhi_null_common_files.cmake # Gems/Atom/RHI/Vulkan/Code/Include/Platform/Android/Atom_RHI_Vulkan_precompiled_Platform.h # Gems/Atom/RHI/Vulkan/Code/Include/Platform/Linux/Atom_RHI_Vulkan_precompiled_Platform.h # Gems/Atom/RHI/Vulkan/Code/Include/Platform/Mac/Atom_RHI_Vulkan_precompiled_Platform.h # Gems/Atom/RHI/Vulkan/Code/Include/Platform/Windows/Atom_RHI_Vulkan_precompiled_Platform.h # Gems/Atom/RHI/Vulkan/Code/Source/Atom_RHI_Vulkan_precompiled.h # Gems/Atom/RHI/Vulkan/Code/Source/RHI/SwapChain.cpp # Gems/Atom/RHI/Vulkan/Code/atom_rhi_vulkan_common_files.cmake # Gems/AtomLyIntegration/AtomFont/Code/Include/AtomLyIntegration/AtomFont/AtomFont_precompiled.h # Gems/Blast/Code/Source/StdAfx.cpp # Gems/Camera/Code/Source/Camera_precompiled.h # Gems/EMotionFX/Code/Source/EMotionFX_precompiled.h # Gems/FastNoise/Code/Source/FastNoise_precompiled.h # Gems/Gestures/Code/Source/Gestures_precompiled.h # Gems/GradientSignal/Code/Source/GradientSignal_precompiled.h # Gems/GraphCanvas/Code/precompiled.h # Gems/ImGui/Code/Source/ImGui_precompiled.h # Gems/InAppPurchases/Code/Source/InAppPurchases_precompiled.h # Gems/LmbrCentral/Code/Source/LmbrCentral_precompiled.h # Gems/LmbrCentral/Code/Tests/ShapeGeometryUtilTest.cpp # Gems/LyShine/Code/Editor/UiCanvasEditor_precompiled.h # Gems/LyShine/Code/Source/Animation/LyShine_precompiled.h # Gems/LyShine/Code/Source/LyShine_precompiled.h # Gems/LyShineExamples/Code/Source/LyShineExamples_precompiled.h # Gems/Maestro/Code/Source/Cinematics/Maestro_precompiled.h # Gems/Maestro/Code/Source/Maestro_precompiled.h # Gems/MessagePopup/Code/Source/MessagePopup_precompiled.h # Gems/Metastream/Code/Source/Metastream_precompiled.h # Gems/Microphone/Code/Source/Microphone_precompiled.h # Gems/Multiplayer/Code/Source/Multiplayer_precompiled.h # Gems/PhysX/Code/NumericalMethods/Source/NumericalMethods_precompiled.h # Gems/PhysX/Code/Source/PhysXUnsupported_precompiled.h # Gems/PhysX/Code/Source/PhysX_precompiled.h # Gems/PhysX/Code/physx_unsupported_files.cmake # Gems/PhysXDebug/Code/Source/PhysXDebugUnsupported_precompiled.h # Gems/PhysXDebug/Code/Source/PhysXDebug_precompiled.h # Gems/ScriptCanvas/Code/Editor/precompiled.h # Gems/ScriptCanvas/Code/Source/precompiled.h # Gems/ScriptCanvasDeveloper/Code/Source/precompiled.h # Gems/ScriptCanvasPhysics/Code/Source/ScriptCanvasPhysics_precompiled.h # Gems/ScriptEvents/Code/Source/precompiled.h # Gems/ScriptEvents/Code/Tests/Editor/EditorTests.cpp # Gems/ScriptedEntityTweener/Code/Source/ScriptedEntityTweener_precompiled.h # Gems/SliceFavorites/Code/Source/SliceFavorites_precompiled.h # Gems/StartingPointCamera/Code/Source/StartingPointCamera_precompiled.h # Gems/StartingPointInput/Code/Source/StartingPointInput_precompiled.h # Gems/StartingPointMovement/Code/Source/StartingPointMovement_precompiled.h # Gems/SurfaceData/Code/Source/SurfaceData_precompiled.h # Gems/TextureAtlas/Code/Source/TextureAtlas_precompiled.h # Gems/TickBusOrderViewer/Code/Source/TickBusOrderViewer_precompiled.h # Gems/Twitch/Code/Source/Twitch_precompiled.h # Gems/VirtualGamepad/Code/Source/VirtualGamepad_precompiled.h # Gems/WhiteBox/Code/Source/WhiteBoxUnsupported_precompiled.h # Gems/WhiteBox/Code/Source/WhiteBox_precompiled.h
472 lines
19 KiB
C++
472 lines
19 KiB
C++
/*
|
|
* Copyright (c) Contributors to the Open 3D Engine Project.
|
|
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
|
*
|
|
*/
|
|
|
|
#include <AzCore/Serialization/EditContext.h>
|
|
#include <AzCore/Serialization/SerializeContext.h>
|
|
#include <AzCore/Component/ComponentApplicationBus.h>
|
|
#include <AzCore/Component/Entity.h>
|
|
#include <AzCore/RTTI/BehaviorContext.h>
|
|
|
|
#include "SimpleStateComponent.h"
|
|
|
|
namespace
|
|
{
|
|
const char * NullStateName = "<None>";
|
|
const char * NewStateName = "New State";
|
|
}
|
|
|
|
namespace LmbrCentral
|
|
{
|
|
// BehaviorContext SimpleStateComponentNotificationBus forwarder
|
|
class BehaviorSimpleStateComponentNotificationBusHandler : public SimpleStateComponentNotificationBus::Handler, public AZ::BehaviorEBusHandler
|
|
{
|
|
public:
|
|
AZ_EBUS_BEHAVIOR_BINDER(BehaviorSimpleStateComponentNotificationBusHandler, "{F935125C-AE4E-48C1-BB60-24A0559BC4D2}", AZ::SystemAllocator,
|
|
OnStateChanged);
|
|
|
|
void OnStateChanged(const char* oldState, const char* newState)
|
|
{
|
|
Call(FN_OnStateChanged, oldState, newState);
|
|
}
|
|
};
|
|
|
|
//=========================================================================
|
|
// ForEachEntity
|
|
//=========================================================================
|
|
template <class Func>
|
|
void ForEachEntity(AZStd::vector<AZ::EntityId>& entitiyIds, Func entityFunction)
|
|
{
|
|
for (const AZ::EntityId& currId : entitiyIds)
|
|
{
|
|
AZ::Entity* entity = nullptr;
|
|
EBUS_EVENT_RESULT(entity, AZ::ComponentApplicationBus, FindEntity, currId);
|
|
if (entity)
|
|
{
|
|
entityFunction(entity);
|
|
}
|
|
}
|
|
}
|
|
|
|
//=========================================================================
|
|
// State::State
|
|
//=========================================================================
|
|
State::State()
|
|
: m_name(NewStateName)
|
|
{
|
|
}
|
|
|
|
//=========================================================================
|
|
// State::Init
|
|
//=========================================================================
|
|
void State::Init()
|
|
{
|
|
UpdateNameCrc();
|
|
for (const AZ::EntityId& currId : m_entityIds)
|
|
{
|
|
// Listen for the entity's initialization so we can adjust initial activation state.
|
|
AZ::EntityBus::MultiHandler::BusConnect(currId);
|
|
}
|
|
}
|
|
|
|
//=========================================================================
|
|
// State::Activate
|
|
//=========================================================================
|
|
void State::Activate()
|
|
{
|
|
ForEachEntity(m_entityIds,
|
|
[](AZ::Entity* entity)
|
|
{
|
|
if (entity->GetState() != AZ::Entity::State::Active)
|
|
{
|
|
entity->Activate();
|
|
}
|
|
}
|
|
);
|
|
}
|
|
|
|
//=========================================================================
|
|
// State::Deactivate
|
|
//=========================================================================
|
|
void State::Deactivate()
|
|
{
|
|
ForEachEntity(m_entityIds,
|
|
[](AZ::Entity* entity)
|
|
{
|
|
if (entity->GetState() == AZ::Entity::State::Active)
|
|
{
|
|
entity->Deactivate();
|
|
}
|
|
}
|
|
);
|
|
}
|
|
|
|
//=========================================================================
|
|
// State::UpdateNameCrc
|
|
//=========================================================================
|
|
void State::UpdateNameCrc()
|
|
{
|
|
m_nameCrc = AZ::Crc32(m_name.c_str());
|
|
}
|
|
|
|
//=========================================================================
|
|
// GetStateFromName
|
|
//=========================================================================
|
|
State* State::FindWithName(AZStd::vector<State>& states, const char* stateName)
|
|
{
|
|
if (stateName)
|
|
{
|
|
const AZ::Crc32 stateNameCrc(stateName);
|
|
for (State& currState : states)
|
|
{
|
|
if ((currState.m_nameCrc == stateNameCrc) && (currState.m_name == stateName))
|
|
{
|
|
return &currState;
|
|
}
|
|
}
|
|
|
|
AZ_Error("SimpleStateComponent", false, "StateName '%s' does not map to any existing states", stateName);
|
|
}
|
|
|
|
return nullptr;
|
|
}
|
|
|
|
//=========================================================================
|
|
// OnEntityExists
|
|
//=========================================================================
|
|
void State::OnEntityExists(const AZ::EntityId& entityId)
|
|
{
|
|
AZ::EntityBus::MultiHandler::BusDisconnect(entityId);
|
|
|
|
// Mark the entity to not be activated by default.
|
|
AZ::Entity* entity = nullptr;
|
|
AZ::ComponentApplicationBus::BroadcastResult(entity, &AZ::ComponentApplicationBus::Events::FindEntity, entityId);
|
|
if (entity && entity->GetState() <= AZ::Entity::State::Init)
|
|
{
|
|
entity->SetRuntimeActiveByDefault(false);
|
|
}
|
|
}
|
|
|
|
//=========================================================================
|
|
// SimpleStateComponent::Reflect
|
|
//=========================================================================
|
|
void State::Reflect(AZ::ReflectContext* context)
|
|
{
|
|
AZ::SerializeContext* serializeContext = azrtti_cast<AZ::SerializeContext*>(context);
|
|
if (serializeContext)
|
|
{
|
|
serializeContext->Class<State>()
|
|
->Version(1)
|
|
->Field("Name", &State::m_name)
|
|
->Field("EntityIds", &State::m_entityIds);
|
|
|
|
AZ::EditContext* editContext = serializeContext->GetEditContext();
|
|
if (editContext)
|
|
{
|
|
editContext->Class<State>("State", "A state includes a name and set of entities that will be activated when the state is entered and deactivated when the state is left.")
|
|
->ClassElement(AZ::Edit::ClassElements::EditorData, "")
|
|
->Attribute(AZ::Edit::Attributes::AutoExpand, true)
|
|
->DataElement(0, &State::m_name, "Name", "The name of this state")
|
|
->Attribute(AZ::Edit::Attributes::ChangeNotify, AZ_CRC("RefreshAttributesAndValues", 0xcbc2147c))
|
|
->DataElement(0, &State::m_entityIds, "Entities", "The list of entities referenced by this state")
|
|
->Attribute(AZ::Edit::Attributes::AutoExpand, true)
|
|
->Attribute(AZ::Edit::Attributes::ChangeNotify, AZ_CRC("RefreshAttributesAndValues", 0xcbc2147c));
|
|
}
|
|
}
|
|
}
|
|
|
|
//=========================================================================
|
|
// SimpleStateComponent::Reflect
|
|
//=========================================================================
|
|
void SimpleStateComponent::Reflect(AZ::ReflectContext* context)
|
|
{
|
|
State::Reflect(context);
|
|
|
|
if (AZ::SerializeContext* serializeContext = azrtti_cast<AZ::SerializeContext*>(context))
|
|
{
|
|
serializeContext->Class<SimpleStateComponent, AZ::Component>()
|
|
->Version(1)
|
|
->Field("InitialStateName", &SimpleStateComponent::m_initialStateName)
|
|
->Field("ResetOnActivate", &SimpleStateComponent::m_resetStateOnActivate)
|
|
->Field("States", &SimpleStateComponent::m_states);
|
|
|
|
AZ::EditContext* editContext = serializeContext->GetEditContext();
|
|
if (editContext)
|
|
{
|
|
editContext->Class<SimpleStateComponent>("Simple State", "The Simple State component provides a simple state machine allowing activation and deactivation of associated entities")
|
|
->ClassElement(AZ::Edit::ClassElements::EditorData, "")
|
|
->Attribute(AZ::Edit::Attributes::Category, "Gameplay")
|
|
->Attribute(AZ::Edit::Attributes::AutoExpand, true)
|
|
->Attribute(AZ::Edit::Attributes::AppearsInAddComponentMenu, AZ_CRC("Game", 0x232b318c))
|
|
->Attribute(AZ::Edit::Attributes::Icon, "Icons/Components/SimpleState.svg")
|
|
->Attribute(AZ::Edit::Attributes::ViewportIcon, "Icons/Components/Viewport/SimpleState.png")
|
|
->Attribute(AZ::Edit::Attributes::HelpPageURL, "https://o3de.org/docs/user-guide/components/reference/simple-state/")
|
|
->DataElement(AZ::Edit::UIHandlers::ComboBox, &SimpleStateComponent::m_initialStateName, "Initial state", "The initial active state")
|
|
->Attribute(AZ::Edit::Attributes::ChangeNotify, AZ_CRC("RefreshAttributesAndValues", 0xcbc2147c))
|
|
->Attribute(AZ::Edit::Attributes::StringList, &SimpleStateComponent::GetStateNames)
|
|
->DataElement(0, &SimpleStateComponent::m_resetStateOnActivate, "Reset on activate", "If set, SimpleState will return to the configured initial state when activated, and not the state held prior to being deactivated.")
|
|
->DataElement(0, &SimpleStateComponent::m_states, "States", "The list of states")
|
|
->Attribute(AZ::Edit::Attributes::AutoExpand, true)
|
|
->Attribute(AZ::Edit::Attributes::ChangeNotify, AZ_CRC("RefreshAttributesAndValues", 0xcbc2147c));
|
|
}
|
|
}
|
|
|
|
AZ::BehaviorContext* behaviorContext = azrtti_cast<AZ::BehaviorContext*>(context);
|
|
if (behaviorContext)
|
|
{
|
|
behaviorContext->EBus<SimpleStateComponentRequestBus>("SimpleStateComponentRequestBus")
|
|
->Event("SetState", &SimpleStateComponentRequestBus::Events::SetState)
|
|
->Event("SetStateByIndex", &SimpleStateComponentRequestBus::Events::SetStateByIndex)
|
|
->Event("SetToNextState", &SimpleStateComponentRequestBus::Events::SetToNextState)
|
|
->Event("SetToPreviousState", &SimpleStateComponentRequestBus::Events::SetToPreviousState)
|
|
->Event("SetToFirstState", &SimpleStateComponentRequestBus::Events::SetToFirstState)
|
|
->Event("SetToLastState", &SimpleStateComponentRequestBus::Events::SetToLastState)
|
|
->Event("GetNumStates", &SimpleStateComponentRequestBus::Events::GetNumStates)
|
|
->Event("GetCurrentState", &SimpleStateComponentRequestBus::Events::GetCurrentState)
|
|
;
|
|
|
|
behaviorContext->EBus<SimpleStateComponentNotificationBus>("SimpleStateComponentNotificationBus")
|
|
->Handler<BehaviorSimpleStateComponentNotificationBusHandler>()
|
|
;
|
|
}
|
|
}
|
|
|
|
//=========================================================================
|
|
// SimpleStateComponent::SimpleStateComponent
|
|
//=========================================================================
|
|
SimpleStateComponent::SimpleStateComponent()
|
|
: m_initialStateName(NullStateName)
|
|
{
|
|
}
|
|
|
|
//=========================================================================
|
|
// SimpleStateComponent::Init
|
|
//=========================================================================
|
|
void SimpleStateComponent::Init()
|
|
{
|
|
for (State& currState : m_states)
|
|
{
|
|
currState.Init();
|
|
}
|
|
|
|
// Prior revisions used the empty string as null state
|
|
const char * initialStateName = (m_initialStateName.empty() || (m_initialStateName == NullStateName)) ? nullptr : m_initialStateName.c_str();
|
|
m_initialState = State::FindWithName(m_states, initialStateName);
|
|
m_currentState = m_initialState;
|
|
}
|
|
|
|
//=========================================================================
|
|
// SimpleStateComponent::Activate
|
|
//=========================================================================
|
|
void SimpleStateComponent::Activate()
|
|
{
|
|
if (m_resetStateOnActivate)
|
|
{
|
|
m_currentState = m_initialState;
|
|
}
|
|
|
|
for (State& currState : m_states)
|
|
{
|
|
if (&currState != m_currentState)
|
|
{
|
|
currState.Deactivate();
|
|
}
|
|
}
|
|
|
|
if (m_currentState)
|
|
{
|
|
m_currentState->Activate();
|
|
}
|
|
|
|
SimpleStateComponentRequestBus::Handler::BusConnect(GetEntityId());
|
|
|
|
if (m_currentState)
|
|
{
|
|
// Notify newly activated State
|
|
// Note: Even if !m_resetStateOnActivate, the prior state to Activation is NullState
|
|
EBUS_EVENT_ID(GetEntityId(), SimpleStateComponentNotificationBus, OnStateChanged, nullptr, m_currentState->GetNameCStr());
|
|
}
|
|
}
|
|
|
|
//=========================================================================
|
|
// SimpleStateComponent::Deactivate
|
|
//=========================================================================
|
|
void SimpleStateComponent::Deactivate()
|
|
{
|
|
SimpleStateComponentRequestBus::Handler::BusDisconnect();
|
|
|
|
if (m_currentState)
|
|
{
|
|
m_currentState->Deactivate();
|
|
}
|
|
}
|
|
|
|
//=========================================================================
|
|
// SimpleStateComponent::SetStateInternal
|
|
//=========================================================================
|
|
void SimpleStateComponent::SetStateInternal(State* newState)
|
|
{
|
|
// Out with the old
|
|
const char* oldName = nullptr;
|
|
if (m_currentState)
|
|
{
|
|
oldName = m_currentState->GetNameCStr();
|
|
m_currentState->Deactivate();
|
|
}
|
|
|
|
// In with the new
|
|
const char* newName = nullptr;
|
|
if (newState)
|
|
{
|
|
newName = newState->GetNameCStr();
|
|
newState->Activate();
|
|
}
|
|
|
|
if (m_currentState != newState)
|
|
{
|
|
m_currentState = newState;
|
|
|
|
EBUS_EVENT_ID(GetEntityId(), SimpleStateComponentNotificationBus, OnStateChanged, oldName, newName);
|
|
}
|
|
}
|
|
|
|
//=========================================================================
|
|
// SimpleStateComponent::SetState
|
|
//=========================================================================
|
|
void SimpleStateComponent::SetState(const char* stateName)
|
|
{
|
|
State* newState = State::FindWithName(m_states, stateName);
|
|
SetStateInternal(newState);
|
|
}
|
|
|
|
//=========================================================================
|
|
// SimpleStateComponent::SetStateByIndex
|
|
//=========================================================================
|
|
void SimpleStateComponent::SetStateByIndex(AZ::u32 stateIndex)
|
|
{
|
|
State* newState;
|
|
if (stateIndex < m_states.size())
|
|
{
|
|
newState = &m_states[stateIndex];
|
|
}
|
|
else
|
|
{
|
|
newState = nullptr;
|
|
AZ_Error("SimpleStateComponent", false, "StateName index '%d' is invalid (currently %d states)", stateIndex, static_cast<AZ::u32>(m_states.size()));
|
|
}
|
|
SetStateInternal(newState);
|
|
}
|
|
|
|
|
|
//=========================================================================
|
|
// SimpleStateComponent::SetToNextState
|
|
//=========================================================================
|
|
void SimpleStateComponent::SetToNextState()
|
|
{
|
|
if (!m_states.empty())
|
|
{
|
|
SetStateToOffset(1, m_states.front());
|
|
}
|
|
}
|
|
|
|
//=========================================================================
|
|
// SimpleStateComponent::SetToPreviousState
|
|
//=========================================================================
|
|
void SimpleStateComponent::SetToPreviousState()
|
|
{
|
|
if (!m_states.empty())
|
|
{
|
|
SetStateToOffset(-1, m_states.back());
|
|
}
|
|
}
|
|
|
|
//=========================================================================
|
|
// SimpleStateComponent::SetStateToOffset
|
|
//=========================================================================
|
|
void SimpleStateComponent::SetStateToOffset(AZ::s32 offset, State& fromNullState)
|
|
{
|
|
AZ_Assert(!m_states.empty(), "violated precondition - must be non-empty");
|
|
|
|
State* newState;
|
|
if (m_currentState)
|
|
{
|
|
const size_t currentStateIndex = m_currentState - &m_states[0];
|
|
AZ_Assert(currentStateIndex < m_states.size(), "Invalid current state pointer");
|
|
|
|
const size_t numStates = m_states.size();
|
|
const size_t newStateIndex = (currentStateIndex + numStates + offset) % numStates;
|
|
AZ_Assert(newStateIndex < numStates, "Invalid negative offset");
|
|
newState = &m_states[newStateIndex];
|
|
}
|
|
else
|
|
{
|
|
// "Advance" to the provided state from NullState
|
|
newState = &fromNullState;
|
|
}
|
|
|
|
SetStateInternal(newState);
|
|
}
|
|
|
|
//=========================================================================
|
|
// SimpleStateComponent::SetToFirstState
|
|
//=========================================================================
|
|
void SimpleStateComponent::SetToFirstState()
|
|
{
|
|
if (!m_states.empty())
|
|
{
|
|
SetStateInternal(&m_states.front());
|
|
}
|
|
}
|
|
|
|
//=========================================================================
|
|
// SimpleStateComponent::SetToLastState
|
|
//=========================================================================
|
|
void SimpleStateComponent::SetToLastState()
|
|
{
|
|
if (!m_states.empty())
|
|
{
|
|
SetStateInternal(&m_states.back());
|
|
}
|
|
}
|
|
|
|
//=========================================================================
|
|
// SimpleStateComponent::GetNumStates
|
|
//=========================================================================
|
|
AZ::u32 SimpleStateComponent::GetNumStates()
|
|
{
|
|
return static_cast<AZ::u32>(m_states.size());
|
|
}
|
|
|
|
//=========================================================================
|
|
// SimpleStateComponent::GetState
|
|
//=========================================================================
|
|
const char* SimpleStateComponent::GetCurrentState()
|
|
{
|
|
return m_currentState ? m_currentState->GetNameCStr() : nullptr;
|
|
}
|
|
|
|
//=========================================================================
|
|
// SimpleStateComponent::GetStateNames
|
|
//=========================================================================
|
|
AZStd::vector<AZStd::string> SimpleStateComponent::GetStateNames() const
|
|
{
|
|
AZStd::vector<AZStd::string> names;
|
|
|
|
names.reserve(m_states.size() + 1);
|
|
|
|
// Provide "no initial state" as an option
|
|
names.emplace_back(NullStateName);
|
|
|
|
for (const State& currState : m_states)
|
|
{
|
|
names.emplace_back(currState.GetName());
|
|
}
|
|
|
|
return names;
|
|
}
|
|
} // namespace LmbrCentral
|