1 // Copyright 2001-2019 Crytek GmbH / Crytek Group. All rights reserved.
4 #include "Script/Elements/ScriptAbstractInterfaceImplementation.h"
6 #include <CrySerialization/BlackBox.h>
7 #include <CrySerialization/IArchiveHost.h>
8 #include <CrySerialization/STL.h>
9 #include <CrySchematyc2/GUIDRemapper.h>
10 #include <CrySchematyc2/IAbstractInterface.h>
11 #include <CrySchematyc2/ICompiler.h>
12 #include <CrySchematyc2/Deprecated/DocUtils.h>
13 #include <CrySchematyc2/Env/IEnvRegistry.h>
14 #include <CrySchematyc2/Script/IScriptGraph.h>
15 #include <CrySchematyc2/Serialization/ISerializationContext.h>
16 #include <CrySchematyc2/Serialization/SerializationUtils.h>
20 //////////////////////////////////////////////////////////////////////////
21 CScriptAbstractInterfaceImplementation::CScriptAbstractInterfaceImplementation(IScriptFile
& file
, const SGUID
& guid
, const SGUID
& scopeGUID
, EDomain domain
, const SGUID
& refGUID
)
22 : CScriptElementBase(EScriptElementType::AbstractInterfaceImplementation
, file
)
24 , m_scopeGUID(scopeGUID
)
29 //////////////////////////////////////////////////////////////////////////
30 EAccessor
CScriptAbstractInterfaceImplementation::GetAccessor() const
32 return EAccessor::Private
;
35 //////////////////////////////////////////////////////////////////////////
36 SGUID
CScriptAbstractInterfaceImplementation::GetGUID() const
41 //////////////////////////////////////////////////////////////////////////
42 SGUID
CScriptAbstractInterfaceImplementation::GetScopeGUID() const
47 //////////////////////////////////////////////////////////////////////////
48 bool CScriptAbstractInterfaceImplementation::SetName(const char* szName
)
53 //////////////////////////////////////////////////////////////////////////
54 const char* CScriptAbstractInterfaceImplementation::GetName() const
56 return m_name
.c_str();
59 //////////////////////////////////////////////////////////////////////////
60 void CScriptAbstractInterfaceImplementation::EnumerateDependencies(const ScriptDependancyEnumerator
& enumerator
) const
62 SCHEMATYC2_SYSTEM_ASSERT(enumerator
);
65 if(m_domain
== EDomain::Script
)
67 enumerator(m_refGUID
);
72 //////////////////////////////////////////////////////////////////////////
73 void CScriptAbstractInterfaceImplementation::Refresh(const SScriptRefreshParams
& params
)
75 if((params
.reason
== EScriptRefreshReason::EditorAdd
) || (params
.reason
== EScriptRefreshReason::EditorFixUp
) || (params
.reason
== EScriptRefreshReason::EditorPaste
) || (params
.reason
== EScriptRefreshReason::EditorDependencyModified
))
81 IAbstractInterfaceConstPtr pAbstractInterface
= gEnv
->pSchematyc2
->GetEnvRegistry().GetAbstractInterface(m_refGUID
);
82 if(pAbstractInterface
)
84 m_name
= pAbstractInterface
->GetName();
85 RefreshEnvAbstractrInterfaceFunctions(*pAbstractInterface
);
91 ScriptIncludeRecursionUtils::TGetAbstractInterfaceResult abstractInterface
= ScriptIncludeRecursionUtils::GetAbstractInterface(CScriptElementBase::GetFile(), m_refGUID
);
92 if(abstractInterface
.second
)
94 m_name
= abstractInterface
.second
->GetName();
95 RefreshScriptAbstractrInterfaceFunctions(*abstractInterface
.first
);
96 RefreshScriptAbstractrInterfaceTasks(*abstractInterface
.first
);
104 //////////////////////////////////////////////////////////////////////////
105 void CScriptAbstractInterfaceImplementation::Serialize(Serialization::IArchive
& archive
)
107 CRY_PROFILE_FUNCTION(PROFILE_LOADING_ONLY
);
109 CScriptElementBase::Serialize(archive
);
111 SerializationContext::SetValidatorLink(archive
, SValidatorLink(m_guid
)); // #SchematycTODO : Can we set this from CScriptElementBase?
112 switch(SerializationContext::GetPass(archive
))
114 case ESerializationPass::PreLoad
:
115 case ESerializationPass::Save
:
117 archive(m_guid
, "guid");
118 archive(m_scopeGUID
, "scope_guid");
119 archive(m_name
, "name");
120 archive(m_domain
, "origin"); // #SchematycTODO : Update name and patch files!
121 archive(m_refGUID
, "abstract_interface_guid");
124 case ESerializationPass::Validate
:
132 //////////////////////////////////////////////////////////////////////////
133 void CScriptAbstractInterfaceImplementation::RemapGUIDs(IGUIDRemapper
& guidRemapper
)
135 m_guid
= guidRemapper
.Remap(m_guid
);
136 m_scopeGUID
= guidRemapper
.Remap(m_scopeGUID
);
137 m_refGUID
= guidRemapper
.Remap(m_refGUID
);
140 //////////////////////////////////////////////////////////////////////////
141 EDomain
CScriptAbstractInterfaceImplementation::GetDomain() const
146 //////////////////////////////////////////////////////////////////////////
147 SGUID
CScriptAbstractInterfaceImplementation::GetRefGUID() const
152 //////////////////////////////////////////////////////////////////////////
153 void CScriptAbstractInterfaceImplementation::RefreshEnvAbstractrInterfaceFunctions(const IAbstractInterface
& abstractInterface
)
156 IScriptFile
& file
= CScriptElementBase::GetFile();
157 TDocGraphVector graphs
;
158 DocUtils::CollectGraphs(file
, m_guid
, false, graphs
);
159 // Iterate through all functions in abstract interface and create corresponding graphs (if they don't already exist).
160 for(size_t functionIdx
= 0, functionCount
= abstractInterface
.GetFunctionCount(); functionIdx
< functionCount
; ++ functionIdx
)
162 IAbstractInterfaceFunctionConstPtr pFunction
= abstractInterface
.GetFunction(functionIdx
);
163 const SGUID functionGUID
= pFunction
->GetGUID();
164 bool bGraphExists
= false;
165 for(const IDocGraph
* pGraph
: graphs
)
167 if(pGraph
->GetContextGUID() == functionGUID
)
175 IDocGraph
* pGraph
= file
.AddGraph(SScriptGraphParams(m_guid
, pFunction
->GetName(), EScriptGraphType::AbstractInterfaceFunction
, functionGUID
));
179 pGraph
->AddNode(EScriptGraphNodeType::Begin
, SGUID(), SGUID(), Vec2(0.0f
, 0.0f
)); // #SchematycTODO : This should be handled by the graph itself!!!
180 graphs
.push_back(pGraph
);
186 //////////////////////////////////////////////////////////////////////////
187 void CScriptAbstractInterfaceImplementation::RefreshScriptAbstractrInterfaceFunctions(const IScriptFile
& abstractrInterfaceFile
)
189 typedef std::map
<SGUID
, IDocGraph
*> FunctionGraphs
;
191 IScriptFile
& file
= CScriptElementBase::GetFile();
192 FunctionGraphs functionGraphs
;
194 auto visitGraph
= [&functionGraphs
] (IDocGraph
& graph
) -> EVisitStatus
196 if(graph
.GetType() == EScriptGraphType::AbstractInterfaceFunction
)
198 functionGraphs
.insert(FunctionGraphs::value_type(graph
.GetContextGUID(), &graph
));
200 return EVisitStatus::Continue
;
202 file
.VisitGraphs(DocGraphVisitor::FromLambdaFunction(visitGraph
), m_guid
, false);
204 auto visitAbstractInterfaceFunction
= [this, &file
, &functionGraphs
] (const IScriptAbstractInterfaceFunction
& function
) -> EVisitStatus
206 const SGUID functionGUID
= function
.GetGUID();
207 FunctionGraphs::iterator itFunctionGraph
= functionGraphs
.find(functionGUID
);
208 if(itFunctionGraph
== functionGraphs
.end())
210 IDocGraph
* pGraph
= file
.AddGraph(SScriptGraphParams(m_guid
, function
.GetName(), EScriptGraphType::AbstractInterfaceFunction
, functionGUID
));
214 pGraph
->AddNode(EScriptGraphNodeType::Begin
, SGUID(), SGUID(), Vec2(0.0f
, 0.0f
)); // #SchematycTODO : This should be handled by the graph itself!!!
219 functionGraphs
.erase(itFunctionGraph
);
221 return EVisitStatus::Continue
;
223 abstractrInterfaceFile
.VisitAbstractInterfaceFunctions(ScriptAbstractInterfaceFunctionConstVisitor::FromLambdaFunction(visitAbstractInterfaceFunction
), m_refGUID
, false);
225 for(FunctionGraphs::value_type
& functionGraph
: functionGraphs
)
227 functionGraph
.second
->SetElementFlags(EScriptElementFlags::Discard
);
231 //////////////////////////////////////////////////////////////////////////
232 void CScriptAbstractInterfaceImplementation::RefreshScriptAbstractrInterfaceTasks(const IScriptFile
& abstractrInterfaceFile
)
234 typedef std::unordered_map
<SGUID
, IScriptStateMachine
*> TaskStateMachines
;
236 IScriptFile
& file
= CScriptElementBase::GetFile();
237 TaskStateMachines taskStateMachines
;
239 auto visitStateMachine
= [&taskStateMachines
] (IScriptStateMachine
& stateMachine
) -> EVisitStatus
241 if(stateMachine
.GetLifetime() == EStateMachineLifetime::Task
)
243 taskStateMachines
.insert(TaskStateMachines::value_type(stateMachine
.GetContextGUID(), &stateMachine
));
245 return EVisitStatus::Continue
;
247 file
.VisitStateMachines(ScriptStateMachineVisitor::FromLambdaFunction(visitStateMachine
), m_guid
, false);
249 auto visitAbstractInterfaceTask
= [this, &abstractrInterfaceFile
, &file
, &taskStateMachines
] (const IScriptAbstractInterfaceTask
& task
) -> EVisitStatus
251 const SGUID taskGUID
= task
.GetGUID();
252 TaskStateMachines::iterator itTaskStateMachine
= taskStateMachines
.find(taskGUID
);
253 if(itTaskStateMachine
== taskStateMachines
.end())
255 file
.AddStateMachine(m_guid
, task
.GetName(), EStateMachineLifetime::Task
, taskGUID
, SGUID());
259 taskStateMachines
.erase(itTaskStateMachine
);
261 RefreshScriptAbstractrInterfaceTaskPropertiess(abstractrInterfaceFile
, taskGUID
);
262 return EVisitStatus::Continue
;
264 abstractrInterfaceFile
.VisitAbstractInterfaceTasks(ScriptAbstractInterfaceTaskConstVisitor::FromLambdaFunction(visitAbstractInterfaceTask
), m_refGUID
, false);
266 for(TaskStateMachines::value_type
& taskStateMachine
: taskStateMachines
)
268 taskStateMachine
.second
->SetElementFlags(EScriptElementFlags::Discard
);
272 //////////////////////////////////////////////////////////////////////////
273 void CScriptAbstractInterfaceImplementation::RefreshScriptAbstractrInterfaceTaskPropertiess(const IScriptFile
& abstractrInterfaceFile
, const SGUID
& taskGUID
) {}
275 //////////////////////////////////////////////////////////////////////////
276 void CScriptAbstractInterfaceImplementation::Validate(Serialization::IArchive
& archive
)
284 IAbstractInterfaceConstPtr pAbstractInterface
= gEnv
->pSchematyc2
->GetEnvRegistry().GetAbstractInterface(m_refGUID
);
285 if(!pAbstractInterface
)
287 archive
.error(*this, "Unable to retrieve abstract interface!");
291 case EDomain::Script
:
293 ScriptIncludeRecursionUtils::TGetAbstractInterfaceResult abstractInterface
= ScriptIncludeRecursionUtils::GetAbstractInterface(CScriptElementBase::GetFile(), m_refGUID
);
294 if(!abstractInterface
.second
)
296 archive
.error(*this, "Unable to retrieve abstract interface!");