1 // Copyright 2001-2019 Crytek GmbH / Crytek Group. All rights reserved.
4 #include "Script/Elements/ScriptStateMachine.h"
6 #include <CrySerialization/IArchiveHost.h>
7 #include <CrySchematyc2/GUIDRemapper.h>
8 #include <CrySchematyc2/Deprecated/DocUtils.h>
9 #include <CrySchematyc2/Script/IScriptGraph.h>
10 #include <CrySchematyc2/Serialization/ISerializationContext.h>
12 #include "DomainContext.h"
14 SERIALIZATION_ENUM_BEGIN_NESTED(Schematyc2
, EStateMachineNetAuthority
, "Schematyc Script State Machine Net Type")
15 SERIALIZATION_ENUM(Schematyc2::EStateMachineNetAuthority::Local
, "local", "Local")
16 SERIALIZATION_ENUM(Schematyc2::EStateMachineNetAuthority::Server
, "server", "Server")
17 SERIALIZATION_ENUM_END()
19 SERIALIZATION_ENUM_BEGIN_NESTED(Schematyc2
, EStateMachineLifetime
, "Schematyc Script State Machine Lifetime")
20 SERIALIZATION_ENUM(Schematyc2::EStateMachineLifetime::Persistent
, "persistent", "Persistent")
21 SERIALIZATION_ENUM(Schematyc2::EStateMachineLifetime::Task
, "task", "Task")
22 SERIALIZATION_ENUM(Schematyc2::EStateMachineLifetime::Unknown
, "unknown", "Unknown")
23 SERIALIZATION_ENUM_END()
27 typedef std::vector
<SGUID
> GUIDVector
;
29 //////////////////////////////////////////////////////////////////////////
30 CScriptStateMachine::CScriptStateMachine(IScriptFile
& file
)
31 : CScriptElementBase(EScriptElementType::StateMachine
, file
)
32 , m_lifetime(EStateMachineLifetime::Persistent
)
33 , m_netAuthority(EStateMachineNetAuthority::Local
)
36 //////////////////////////////////////////////////////////////////////////
37 CScriptStateMachine::CScriptStateMachine(IScriptFile
& file
, const SGUID
& guid
, const SGUID
& scopeGUID
, const char* szName
, EStateMachineLifetime lifetime
, const SGUID
& contextGUID
, const SGUID
& partnerGUID
)
38 : CScriptElementBase(EScriptElementType::StateMachine
, file
)
40 , m_scopeGUID(scopeGUID
)
42 , m_lifetime(lifetime
)
43 , m_netAuthority(EStateMachineNetAuthority::Local
)
44 , m_contextGUID(contextGUID
)
45 , m_partnerGUID(partnerGUID
)
48 //////////////////////////////////////////////////////////////////////////
49 EAccessor
CScriptStateMachine::GetAccessor() const
51 return EAccessor::Private
;
54 //////////////////////////////////////////////////////////////////////////
55 SGUID
CScriptStateMachine::GetGUID() const
60 //////////////////////////////////////////////////////////////////////////
61 SGUID
CScriptStateMachine::GetScopeGUID() const
66 //////////////////////////////////////////////////////////////////////////
67 bool CScriptStateMachine::SetName(const char* szName
)
73 //////////////////////////////////////////////////////////////////////////
74 const char* CScriptStateMachine::GetName() const
76 return m_name
.c_str();
79 //////////////////////////////////////////////////////////////////////////
80 void CScriptStateMachine::EnumerateDependencies(const ScriptDependancyEnumerator
& enumerator
) const {}
82 //////////////////////////////////////////////////////////////////////////
83 void CScriptStateMachine::Refresh(const SScriptRefreshParams
& params
)
87 case EScriptRefreshReason::EditorAdd
:
88 case EScriptRefreshReason::EditorFixUp
:
89 case EScriptRefreshReason::EditorPaste
:
91 RefreshTransitionGraph();
97 //////////////////////////////////////////////////////////////////////////
98 void CScriptStateMachine::Serialize(Serialization::IArchive
& archive
)
100 CRY_PROFILE_FUNCTION(PROFILE_LOADING_ONLY
);
102 CScriptElementBase::Serialize(archive
);
104 SerializationContext::SetValidatorLink(archive
, SValidatorLink(m_guid
)); // #SchematycTODO : Can we set this from CScriptElementBase?
105 switch(SerializationContext::GetPass(archive
))
107 case ESerializationPass::PreLoad
:
108 case ESerializationPass::Save
:
110 Serialization::SContext
fileContext(archive
, static_cast<IScriptFile
*>(&CScriptElementBase::GetFile())); // #SchematycTODO : Do we still need this?
112 archive(m_guid
, "guid");
113 archive(m_scopeGUID
, "scope_guid");
114 archive(m_name
, "name");
115 archive(m_lifetime
, "lifetime", "!Lifetime");
116 archive(m_contextGUID
, "contextGUID");
117 archive(m_transitionGraphGUID
, "transition_graph_guid");
118 archive(m_netAuthority
, "netType");
120 SerializePartner(archive
);
123 case ESerializationPass::Edit
:
125 SerializePartner(archive
);
126 archive(m_netAuthority
, "netAuthority", "Net Authority");
127 archive
.doc("Indicates if the state machine will have authority locally(server or authorized client) or on the server.");
133 //////////////////////////////////////////////////////////////////////////
134 void CScriptStateMachine::RemapGUIDs(IGUIDRemapper
& guidRemapper
)
136 m_guid
= guidRemapper
.Remap(m_guid
);
137 m_scopeGUID
= guidRemapper
.Remap(m_scopeGUID
);
138 m_partnerGUID
= guidRemapper
.Remap(m_partnerGUID
);
139 m_contextGUID
= guidRemapper
.Remap(m_contextGUID
);
140 m_transitionGraphGUID
= guidRemapper
.Remap(m_transitionGraphGUID
);
143 //////////////////////////////////////////////////////////////////////////
144 EStateMachineLifetime
CScriptStateMachine::GetLifetime() const
149 EStateMachineNetAuthority
CScriptStateMachine::GetNetAuthority() const
151 return m_netAuthority
;
154 //////////////////////////////////////////////////////////////////////////
155 SGUID
CScriptStateMachine::GetContextGUID() const
157 return m_contextGUID
;
160 //////////////////////////////////////////////////////////////////////////
161 SGUID
CScriptStateMachine::GetPartnerGUID() const
163 return m_partnerGUID
;
166 //////////////////////////////////////////////////////////////////////////
167 void CScriptStateMachine::RefreshTransitionGraph()
171 IScriptFile
& file
= CScriptElementBase::GetFile();
172 if(!m_transitionGraphGUID
|| !file
.GetGraph(m_transitionGraphGUID
))
174 IDocGraph
* pTransitionGraph
= file
.AddGraph(SScriptGraphParams(m_guid
, "Transitions", EScriptGraphType::Transition
, SGUID()));
175 SCHEMATYC2_SYSTEM_ASSERT(pTransitionGraph
);
178 IScriptGraphNode
* pBeginNode
= pTransitionGraph
->AddNode(EScriptGraphNodeType::BeginState
, SGUID(), SGUID(), Vec2(0.0f
, 0.0f
));
179 if(m_lifetime
== EStateMachineLifetime::Task
)
181 IScriptGraphNode
* pEndNode
= pTransitionGraph
->AddNode(EScriptGraphNodeType::EndState
, SGUID(), SGUID(), Vec2(200.0f
, 0.0f
));
182 pTransitionGraph
->AddLink(pBeginNode
->GetGUID(), pBeginNode
->GetOutputName(0), pEndNode
->GetGUID(), pEndNode
->GetInputName(0));
184 m_transitionGraphGUID
= pTransitionGraph
->GetGUID();
190 //////////////////////////////////////////////////////////////////////////
191 void CScriptStateMachine::SerializePartner(Serialization::IArchive
& archive
)
195 GUIDVector partnerGUIDs
;
196 Serialization::StringList partnerNames
;
197 partnerGUIDs
.reserve(16);
198 partnerNames
.reserve(16);
199 partnerGUIDs
.push_back(SGUID());
200 partnerNames
.push_back("None");
202 auto visitStateMachine
= [this, &partnerGUIDs
, &partnerNames
] (const IScriptStateMachine
& stateMachine
) -> EVisitStatus
204 if(stateMachine
.GetLifetime() == EStateMachineLifetime::Persistent
)
206 const SGUID stateMachineGUID
= stateMachine
.GetGUID();
207 if(stateMachineGUID
!= m_guid
)
209 partnerGUIDs
.push_back(stateMachineGUID
);
210 partnerNames
.push_back(stateMachine
.GetName());
213 return EVisitStatus::Continue
;
215 CDomainContext(SDomainContextScope(&CScriptElementBase::GetFile(), m_scopeGUID
)).VisitScriptStateMachines(ScriptStateMachineConstVisitor::FromLambdaFunction(visitStateMachine
), EDomainScope::Local
);
217 GUIDVector::const_iterator itPartnerGUID
= std::find(partnerGUIDs
.begin(), partnerGUIDs
.end(), m_partnerGUID
);
218 const int partnerIdx
= itPartnerGUID
!= partnerGUIDs
.end() ? static_cast<int>(itPartnerGUID
- partnerGUIDs
.begin()) : 0;
219 Serialization::StringListValue
partnerName(partnerNames
, partnerIdx
);
220 archive(partnerName
, "partnerName", "Partner");
221 if(archive
.isInput())
223 m_partnerGUID
= partnerGUIDs
[partnerName
.index()];
228 archive(m_partnerGUID
, "partnerGUID");