1 // Copyright 2001-2019 Crytek GmbH / Crytek Group. All rights reserved.
4 #include "DocGraphBase.h"
6 #include <CrySerialization/BlackBox.h>
7 #include <CrySerialization/IArchiveHost.h>
8 #include <CrySerialization/STL.h>
9 #include <CrySchematyc2/GUIDRemapper.h>
10 #include <CrySchematyc2/Deprecated/DocUtils.h>
11 #include <CrySchematyc2/Serialization/ISerializationContext.h>
12 #include <CrySchematyc2/Services/ILog.h>
16 namespace DocGraphBaseUtils
21 : type(EScriptGraphNodeType::Unknown
)
25 inline SNodeHeader(const SGUID
& _guid
, EScriptGraphNodeType _type
, const SGUID
& _contextGUID
, const SGUID
& _refGUID
, const Vec2
& _pos
)
28 , contextGUID(_contextGUID
)
33 void Serialize(Serialization::IArchive
& archive
)
35 archive(guid
, "guid");
36 archive(type
, "type");
37 archive(contextGUID
, "context_guid");
38 archive(refGUID
, "ref_guid");
43 EScriptGraphNodeType type
;
49 struct SNodeMapValueSerializer
51 inline SNodeMapValueSerializer(std::pair
<SGUID
, SDocGraphNode
>& _value
)
55 void Serialize(Serialization::IArchive
& archive
)
57 CDocGraphBase
* pDocGraph
= archive
.context
<CDocGraphBase
>();
58 CRY_ASSERT(pDocGraph
);
61 pDocGraph
->SerializeNodeMapValue(archive
, value
);
65 std::pair
<SGUID
, SDocGraphNode
>& value
;
70 namespace std
// In order to resolve ADL, std type serialization overrides must be placed in std namespace.
72 inline bool Serialize(Serialization::IArchive
& archive
, pair
<Schematyc2::SGUID
, Schematyc2::SDocGraphNode
>& value
, const char* szName
, const char* szLabel
)
74 archive(Schematyc2::DocGraphBaseUtils::SNodeMapValueSerializer(value
), szName
, szLabel
);
78 /*inline bool Serialize(Serialization::IArchive& archive, shared_ptr<Schematyc2::CScriptGraphLink>& value, const char* szName, const char* szLabel)
82 value = std::make_shared<Schematyc2::CScriptGraphLink>();
84 archive(*value, szName, szLabel);
91 //////////////////////////////////////////////////////////////////////////
92 SDocGraphNode::SDocGraphNode() {}
94 //////////////////////////////////////////////////////////////////////////
95 SDocGraphNode::SDocGraphNode(const IScriptGraphNodePtr
& _pNode
)
99 //////////////////////////////////////////////////////////////////////////
100 CScriptGraphLink::CScriptGraphLink(const SGUID
& srcNodeGUID
, const char* szSrcOutputName
, const SGUID
& dstNodeGUID
, const char* szDstInputName
)
101 : m_srcNodeGUID(srcNodeGUID
)
102 , m_srcOutputName(szSrcOutputName
)
103 , m_dstNodeGUID(dstNodeGUID
)
104 , m_dstInputName(szDstInputName
)
107 //////////////////////////////////////////////////////////////////////////
108 void CScriptGraphLink::SetSrcNodeGUID(const SGUID
& guid
)
110 m_srcNodeGUID
= guid
;
113 //////////////////////////////////////////////////////////////////////////
114 SGUID
CScriptGraphLink::GetSrcNodeGUID() const
116 return m_srcNodeGUID
;
119 //////////////////////////////////////////////////////////////////////////
120 const char* CScriptGraphLink::GetSrcOutputName() const
122 return m_srcOutputName
.c_str();
125 //////////////////////////////////////////////////////////////////////////
126 void CScriptGraphLink::SetDstNodeGUID(const SGUID
& guid
)
128 m_dstNodeGUID
= guid
;
131 //////////////////////////////////////////////////////////////////////////
132 SGUID
CScriptGraphLink::GetDstNodeGUID() const
134 return m_dstNodeGUID
;
137 //////////////////////////////////////////////////////////////////////////
138 const char* CScriptGraphLink::GetDstInputName() const
140 return m_dstInputName
.c_str();
143 //////////////////////////////////////////////////////////////////////////
144 void CScriptGraphLink::Serialize(Serialization::IArchive
& archive
)
146 CRY_PROFILE_FUNCTION(PROFILE_LOADING_ONLY
);
147 if(!archive
.isEdit())
149 archive(m_srcNodeGUID
, "src_node_guid");
150 archive(m_srcOutputName
, "src_output_name");
151 archive(m_dstNodeGUID
, "dst_node_guid");
152 archive(m_dstInputName
, "dst_input_name");
156 //////////////////////////////////////////////////////////////////////////
157 CDocGraphBase::CDocGraphBase(IScriptFile
& file
, const SGUID
& guid
, const SGUID
& scopeGUID
, const char* szName
, EScriptGraphType type
, const SGUID
& contextGUID
)
158 : CScriptElementBase(EScriptElementType::Graph
, file
)
160 , m_scopeGUID(scopeGUID
)
163 , m_contextGUID(contextGUID
)
167 //////////////////////////////////////////////////////////////////////////
168 SGUID
CDocGraphBase::GetGUID() const
173 //////////////////////////////////////////////////////////////////////////
174 SGUID
CDocGraphBase::GetScopeGUID() const
179 //////////////////////////////////////////////////////////////////////////
180 bool CDocGraphBase::SetName(const char* szName
)
186 //////////////////////////////////////////////////////////////////////////
187 const char* CDocGraphBase::GetName() const
189 return m_name
.c_str();
192 //////////////////////////////////////////////////////////////////////////
193 void CDocGraphBase::EnumerateDependencies(const ScriptDependancyEnumerator
& enumerator
) const
195 SCHEMATYC2_SYSTEM_ASSERT(enumerator
);
200 enumerator(m_contextGUID
);
202 for(const CScriptVariableDeclaration
& input
: m_inputs
)
204 input
.EnumerateDependencies(enumerator
);
206 for(const CScriptVariableDeclaration
& output
: m_outputs
)
208 output
.EnumerateDependencies(enumerator
);
213 //////////////////////////////////////////////////////////////////////////
214 void CDocGraphBase::Refresh(const SScriptRefreshParams
& params
)
216 for(DocGraphNodeMap::value_type
& node
: m_nodes
)
218 node
.second
.pNode
->Refresh(params
);
223 //////////////////////////////////////////////////////////////////////////
224 void CDocGraphBase::Serialize(Serialization::IArchive
& archive
)
226 CRY_PROFILE_FUNCTION(PROFILE_LOADING_ONLY
);
228 SerializationContext::SetValidatorLink(archive
, SValidatorLink(m_guid
)); // #SchematycTODO : This should be handled by derived classes!
230 switch(SerializationContext::GetPass(archive
))
232 case ESerializationPass::PreLoad
:
234 archive(m_pos
, "pos");
235 switch(m_type
) // #SchematycTODO : Ideally it should be the implementation that decides whether or not to serialize inputs and outputs.
237 case EScriptGraphType::Function
:
238 case EScriptGraphType::Condition
:
240 archive(m_inputs
, "inputs", "Inputs");
241 archive(m_outputs
, "outputs", "Outputs");
245 Serialization::SContext
fileContext(archive
, static_cast<IScriptFile
*>(&CScriptElementBase::GetFile())); // #SchematycTODO : Do we really need this?
246 Serialization::SContext
docGraphContext(archive
, static_cast<CDocGraphBase
*>(this)); // #SchematycTODO : Do we really need this?
247 yasli::SerializeMapAsVector
<DocGraphNodeMap
, SGUID
, SDocGraphNode
>(archive
, m_nodes
, "nodes", "nodes");
250 case ESerializationPass::Load
:
252 switch(m_type
) // #SchematycTODO : Ideally it should be the implementation that decides whether or not to serialize inputs and outputs.
254 case EScriptGraphType::Function
:
255 case EScriptGraphType::Condition
:
257 archive(m_inputs
, "inputs", "Inputs");
258 archive(m_outputs
, "outputs", "Outputs");
264 case ESerializationPass::PostLoad
:
266 Serialization::SContext
fileContext(archive
, static_cast<IScriptFile
*>(&CScriptElementBase::GetFile())); // #SchematycTODO : Do we really need this?
267 Serialization::SContext
docGraphContext(archive
, static_cast<CDocGraphBase
*>(this)); // #SchematycTODO : Do we really need this?
268 yasli::SerializeMapAsVector
<DocGraphNodeMap
, SGUID
, SDocGraphNode
>(archive
, m_nodes
, "nodes", "nodes");
269 archive(m_links
, "links");
272 case ESerializationPass::Save
:
274 SInfoSerializer(*this).Serialize(archive
);
275 SDataSerializer(*this).Serialize(archive
);
276 SNodeAndLinkSerializer(*this).Serialize(archive
);
279 case ESerializationPass::Edit
:
281 archive(m_name
, "name", "!Name");
287 //////////////////////////////////////////////////////////////////////////
288 void CDocGraphBase::RemapGUIDs(IGUIDRemapper
& guidRemapper
)
290 m_guid
= guidRemapper
.Remap(m_guid
);
291 m_scopeGUID
= guidRemapper
.Remap(m_scopeGUID
);
292 m_contextGUID
= guidRemapper
.Remap(m_contextGUID
);
293 for(CScriptVariableDeclaration
& input
: m_inputs
)
295 input
.RemapGUIDs(guidRemapper
);
297 for(CScriptVariableDeclaration
& output
: m_outputs
)
299 output
.RemapGUIDs(guidRemapper
);
301 for(DocGraphNodeMap::value_type
& node
: m_nodes
)
303 node
.second
.pNode
->RemapGUIDs(guidRemapper
);
307 //////////////////////////////////////////////////////////////////////////
308 EScriptGraphType
CDocGraphBase::GetType() const
313 //////////////////////////////////////////////////////////////////////////
314 SGUID
CDocGraphBase::GetContextGUID() const
316 return m_contextGUID
;
319 //////////////////////////////////////////////////////////////////////////
320 void CDocGraphBase::SetPos(Vec2 pos
)
325 //////////////////////////////////////////////////////////////////////////
326 Vec2
CDocGraphBase::GetPos() const
331 //////////////////////////////////////////////////////////////////////////
332 size_t CDocGraphBase::GetInputCount() const
334 return m_inputs
.size();
337 //////////////////////////////////////////////////////////////////////////
338 const char* CDocGraphBase::GetInputName(size_t inputIdx
) const
340 return inputIdx
< m_inputs
.size() ? m_inputs
[inputIdx
].GetName() : "";
343 //////////////////////////////////////////////////////////////////////////
344 IAnyConstPtr
CDocGraphBase::GetInputValue(size_t inputIdx
) const
346 return inputIdx
< m_inputs
.size() ? m_inputs
[inputIdx
].GetValue() : IAnyConstPtr();
349 //////////////////////////////////////////////////////////////////////////
350 size_t CDocGraphBase::GetOutputCount() const
352 return m_outputs
.size();
355 //////////////////////////////////////////////////////////////////////////
356 const char* CDocGraphBase::GetOutputName(size_t outputIdx
) const
358 return outputIdx
< m_outputs
.size() ? m_outputs
[outputIdx
].GetName() : "";
361 //////////////////////////////////////////////////////////////////////////
362 IAnyConstPtr
CDocGraphBase::GetOutputValue(size_t outputIdx
) const
364 return outputIdx
< m_outputs
.size() ? m_outputs
[outputIdx
].GetValue() : IAnyConstPtr();
367 //////////////////////////////////////////////////////////////////////////
368 size_t CDocGraphBase::GetAvailableNodeCount()
370 return m_availableNodes
.size();
373 //////////////////////////////////////////////////////////////////////////
374 const char* CDocGraphBase::GetAvailableNodeName(size_t availableNodeIdx
) const
376 return availableNodeIdx
< m_availableNodes
.size() ? m_availableNodes
[availableNodeIdx
].name
.c_str() : "";
379 //////////////////////////////////////////////////////////////////////////
380 EScriptGraphNodeType
CDocGraphBase::GetAvailableNodeType(size_t availableNodeIdx
) const
382 return availableNodeIdx
< m_availableNodes
.size() ? m_availableNodes
[availableNodeIdx
].type
: EScriptGraphNodeType::Unknown
;
385 //////////////////////////////////////////////////////////////////////////
386 SGUID
CDocGraphBase::GetAvailableNodeContextGUID(size_t availableNodeIdx
) const
388 return availableNodeIdx
< m_availableNodes
.size() ? m_availableNodes
[availableNodeIdx
].contextGUID
: SGUID();
391 //////////////////////////////////////////////////////////////////////////
392 SGUID
CDocGraphBase::GetAvailableNodeRefGUID(size_t availableNodeIdx
) const
394 return availableNodeIdx
< m_availableNodes
.size() ? m_availableNodes
[availableNodeIdx
].refGUID
: SGUID();
397 //////////////////////////////////////////////////////////////////////////
398 IScriptGraphNode
* CDocGraphBase::AddNode(EScriptGraphNodeType type
, const SGUID
& contextGUID
, const SGUID
& refGUID
, Vec2 pos
)
400 SCHEMATYC2_SYSTEM_ASSERT(gEnv
->IsEditor());
403 const SGUID guid
= gEnv
->pSchematyc2
->CreateGUID();
406 IScriptGraphNodePtr pNode
= CreateNode(guid
, type
, contextGUID
, refGUID
, pos
);
410 m_nodes
.insert(DocGraphNodeMap::value_type(guid
, pNode
));
418 //////////////////////////////////////////////////////////////////////////
419 void CDocGraphBase::RemoveNode(const SGUID
& guid
)
421 IScriptGraphNode
* pNode
= GetNode(guid
);
422 SCHEMATYC2_SYSTEM_ASSERT(pNode
);
429 //////////////////////////////////////////////////////////////////////////
430 IScriptGraphNode
* CDocGraphBase::GetNode(const SGUID
& guid
)
432 DocGraphNodeMap::iterator itNode
= m_nodes
.find(guid
);
433 return itNode
!= m_nodes
.end() ? itNode
->second
.pNode
.get() : nullptr;
436 //////////////////////////////////////////////////////////////////////////
437 const IScriptGraphNode
* CDocGraphBase::GetNode(const SGUID
& guid
) const
439 DocGraphNodeMap::const_iterator itNode
= m_nodes
.find(guid
);
440 return itNode
!= m_nodes
.end() ? itNode
->second
.pNode
.get() : nullptr;
443 //////////////////////////////////////////////////////////////////////////
444 void CDocGraphBase::VisitNodes(const ScriptGraphNodeVisitor
& visitor
)
446 SCHEMATYC2_SYSTEM_ASSERT(visitor
);
449 for(DocGraphNodeMap::value_type
& node
: m_nodes
)
451 if(visitor(*node
.second
.pNode
) != EVisitStatus::Continue
)
459 //////////////////////////////////////////////////////////////////////////
460 void CDocGraphBase::VisitNodes(const ScriptGraphNodeConstVisitor
& visitor
) const
462 SCHEMATYC2_SYSTEM_ASSERT(visitor
);
465 for(const DocGraphNodeMap::value_type
& node
: m_nodes
)
467 if(visitor(*node
.second
.pNode
) != EVisitStatus::Continue
)
475 //////////////////////////////////////////////////////////////////////////
476 bool CDocGraphBase::CanAddLink(const SGUID
& srcNodeGUID
, const char* szScOutputName
, const SGUID
& dstNodeGUID
, const char* szDstInputName
) const
478 const IScriptGraphNode
* pSrcNode
= CDocGraphBase::GetNode(srcNodeGUID
);
479 const IScriptGraphNode
* pDstNode
= CDocGraphBase::GetNode(dstNodeGUID
);
480 SCHEMATYC2_SYSTEM_ASSERT(pSrcNode
&& pDstNode
);
481 if(pSrcNode
&& pDstNode
)
483 const size_t srcOutputIdx
= DocUtils::FindGraphNodeOutput(*pSrcNode
, szScOutputName
);
484 const size_t dstInputIdx
= DocUtils::FindGraphNodeInput(*pDstNode
, szDstInputName
);
485 SCHEMATYC2_SYSTEM_ASSERT((srcOutputIdx
!= INVALID_INDEX
) && (dstInputIdx
!= INVALID_INDEX
));
486 if((srcOutputIdx
!= INVALID_INDEX
) && (dstInputIdx
!= INVALID_INDEX
))
488 const EScriptGraphPortFlags srcOutputFlags
= pSrcNode
->GetOutputFlags(srcOutputIdx
);
489 const EScriptGraphPortFlags dstInputFlags
= pDstNode
->GetInputFlags(dstInputIdx
);
490 const CAggregateTypeId srcOutputTypeId
= pSrcNode
->GetOutputTypeId(srcOutputIdx
);
491 const CAggregateTypeId dstInputTypeId
= pDstNode
->GetInputTypeId(dstInputIdx
);
492 if((((srcOutputFlags
& EScriptGraphPortFlags::Execute
) != 0) && ((dstInputFlags
& EScriptGraphPortFlags::Execute
) != 0)) || (srcOutputTypeId
== dstInputTypeId
))
494 if((pSrcNode
->GetOutputFlags(srcOutputIdx
) & EScriptGraphPortFlags::MultiLink
) == 0)
496 TScriptGraphLinkConstVector srcOutputLinks
;
497 DocUtils::CollectGraphNodeOutputLinks(*this, srcNodeGUID
, pSrcNode
->GetOutputName(srcOutputIdx
), srcOutputLinks
);
498 if(!srcOutputLinks
.empty())
503 if((pDstNode
->GetInputFlags(dstInputIdx
) & EScriptGraphPortFlags::MultiLink
) == 0)
505 TScriptGraphLinkConstVector dstInputLinks
;
506 DocUtils::CollectGraphNodeInputLinks(*this, dstNodeGUID
, pDstNode
->GetInputName(dstInputIdx
), dstInputLinks
);
507 if(!dstInputLinks
.empty())
512 if(CDocGraphBase::FindLink(srcNodeGUID
, pSrcNode
->GetOutputName(srcOutputIdx
), dstNodeGUID
, pDstNode
->GetInputName(dstInputIdx
)) != INVALID_INDEX
)
516 // Trace back along sequence to make sure we're not creating a loop.
517 if(DocUtils::IsPrecedingNodeInGraphSequence(*this, *pSrcNode
, dstNodeGUID
))
528 //////////////////////////////////////////////////////////////////////////
529 IScriptGraphLink
* CDocGraphBase::AddLink(const SGUID
& srcNodeGUID
, const char* szSrcOutputName
, const SGUID
& dstNodeGUID
, const char* szDstInputName
)
531 if(FindLink(srcNodeGUID
, szSrcOutputName
, dstNodeGUID
, szDstInputName
))
533 CScriptGraphLinkPtr
pLink(new CScriptGraphLink(srcNodeGUID
, szSrcOutputName
, dstNodeGUID
, szDstInputName
));
534 m_links
.push_back(pLink
);
540 //////////////////////////////////////////////////////////////////////////
541 void CDocGraphBase::RemoveLink(size_t linkIdx
)
543 const size_t linkCount
= m_links
.size();
544 SCHEMATYC2_SYSTEM_ASSERT(linkIdx
< linkCount
);
545 if(linkIdx
< linkCount
)
547 m_signals
.linkRemoved
.Send(*m_links
[linkIdx
]);
548 m_links
.erase(m_links
.begin() + linkIdx
);
552 //////////////////////////////////////////////////////////////////////////
553 void CDocGraphBase::RemoveLinks(const SGUID
& nodeGUID
)
555 // #SchematycTODO : We can probably optimize this a bit.
556 for(size_t linkIdx
= 0, linkCount
= m_links
.size(); linkIdx
< linkCount
; )
558 if((m_links
[linkIdx
]->GetSrcNodeGUID() == nodeGUID
) || (m_links
[linkIdx
]->GetDstNodeGUID() == nodeGUID
))
560 m_signals
.linkRemoved
.Send(*m_links
[linkIdx
]);
561 m_links
.erase(m_links
.begin() + linkIdx
);
571 //////////////////////////////////////////////////////////////////////////
572 size_t CDocGraphBase::GetLinkCount() const
574 return m_links
.size();
577 //////////////////////////////////////////////////////////////////////////
578 size_t CDocGraphBase::FindLink(const SGUID
& srcGUID
, const char* szSrcOutputName
, const SGUID
& dstNodeGUID
, const char* szDstInputName
) const
580 SCHEMATYC2_SYSTEM_ASSERT(szSrcOutputName
&& szDstInputName
);
581 if(szSrcOutputName
&& szDstInputName
)
583 for(LinkVector::const_iterator iBeginLink
= m_links
.begin(), iEndLink
= m_links
.end(), iLink
= iBeginLink
; iLink
!= iEndLink
; ++ iLink
)
585 const CScriptGraphLink
& link
= *(*iLink
);
586 if((link
.GetSrcNodeGUID() == srcGUID
) && (link
.GetDstNodeGUID() == dstNodeGUID
) && (strcmp(link
.GetSrcOutputName(), szSrcOutputName
) == 0) && (strcmp(link
.GetDstInputName(), szDstInputName
) == 0))
588 return iLink
- iBeginLink
;
592 return INVALID_INDEX
;
595 //////////////////////////////////////////////////////////////////////////
596 IScriptGraphLink
* CDocGraphBase::GetLink(size_t linkIdx
)
598 return linkIdx
< m_links
.size() ? m_links
[linkIdx
].get() : nullptr;
601 //////////////////////////////////////////////////////////////////////////
602 const IScriptGraphLink
* CDocGraphBase::GetLink(size_t linkIdx
) const
604 return linkIdx
< m_links
.size() ? m_links
[linkIdx
].get() : nullptr;
607 //////////////////////////////////////////////////////////////////////////
608 void CDocGraphBase::VisitLinks(const ScriptGraphLinkVisitor
& visitor
)
610 SCHEMATYC2_SYSTEM_ASSERT(visitor
);
613 for(CScriptGraphLinkPtr
& pLink
: m_links
)
615 if(visitor(*pLink
) != EVisitStatus::Continue
)
623 //////////////////////////////////////////////////////////////////////////
624 void CDocGraphBase::VisitLinks(const ScriptGraphLinkConstVisitor
& visitor
) const
626 SCHEMATYC2_SYSTEM_ASSERT(visitor
);
629 for(const CScriptGraphLinkPtr
& pLink
: m_links
)
631 if(visitor(*pLink
) != EVisitStatus::Continue
)
639 //////////////////////////////////////////////////////////////////////////
640 void CDocGraphBase::RemoveBrokenLinks()
642 size_t linkCount
= m_links
.size();
643 for(size_t linkIdx
= 0; linkIdx
< linkCount
; )
645 CScriptGraphLink
& link
= *m_links
[linkIdx
];
646 if(IsBrokenLink(link
))
648 m_signals
.linkRemoved
.Send(link
);
650 if(linkIdx
< linkCount
)
652 m_links
[linkIdx
] = m_links
[linkCount
];
660 m_links
.resize(linkCount
);
663 //////////////////////////////////////////////////////////////////////////
664 SScriptGraphSignals
& CDocGraphBase::Signals()
669 //////////////////////////////////////////////////////////////////////////
670 void CDocGraphBase::SerializeNodeMapValue(Serialization::IArchive
& archive
, std::pair
<SGUID
, SDocGraphNode
>& value
)
672 SerializationContext::SetValidatorLink(archive
, SValidatorLink(m_guid
));
674 switch(SerializationContext::GetPass(archive
))
676 case ESerializationPass::PreLoad
:
678 DocGraphBaseUtils::SNodeHeader nodeHeader
;
679 archive(nodeHeader
, "header");
680 IScriptGraphNodePtr pNode
= CreateNode(nodeHeader
.guid
, nodeHeader
.type
, nodeHeader
.contextGUID
, nodeHeader
.refGUID
, nodeHeader
.pos
);
681 SCHEMATYC2_SYSTEM_ASSERT(pNode
);
684 value
.first
= nodeHeader
.guid
;
685 value
.second
= pNode
;
686 // Hack to fix cloning of state nodes.
687 if(nodeHeader
.type
== EScriptGraphNodeType::State
)
689 archive(*value
.second
.pNode
, "detail");
694 case ESerializationPass::PostLoad
:
696 archive(*value
.second
.pNode
, "detail");
699 case ESerializationPass::Save
:
701 IScriptGraphNode
& node
= *value
.second
.pNode
;
702 DocGraphBaseUtils::SNodeHeader
nodeHeader(node
.GetGUID(), node
.GetType(), node
.GetContextGUID(), node
.GetRefGUID(), node
.GetPos());
703 archive(nodeHeader
, "header");
704 archive(node
, "detail");
710 //////////////////////////////////////////////////////////////////////////
711 void CDocGraphBase::AddAvailableNode(const char* szName
, EScriptGraphNodeType type
, const SGUID
& contextGUID
, const SGUID
& refGUID
)
713 m_availableNodes
.push_back(SAvailableNode(szName
, type
, contextGUID
, refGUID
));
716 //////////////////////////////////////////////////////////////////////////
717 void CDocGraphBase::ClearAvailablNodes()
719 m_availableNodes
.clear();
722 //////////////////////////////////////////////////////////////////////////
723 ScriptVariableDeclarationVector
& CDocGraphBase::GetInputs()
728 //////////////////////////////////////////////////////////////////////////
729 ScriptVariableDeclarationVector
& CDocGraphBase::GetOutputs()
734 //////////////////////////////////////////////////////////////////////////
735 CDocGraphBase::SInfoSerializer::SInfoSerializer(CDocGraphBase
& _graph
)
739 //////////////////////////////////////////////////////////////////////////
740 void CDocGraphBase::SInfoSerializer::Serialize(Serialization::IArchive
& archive
)
742 archive(graph
.m_pos
, "pos");
745 //////////////////////////////////////////////////////////////////////////
746 CDocGraphBase::SDataSerializer::SDataSerializer(CDocGraphBase
& _graph
)
750 //////////////////////////////////////////////////////////////////////////
751 void CDocGraphBase::SDataSerializer::Serialize(Serialization::IArchive
& archive
)
753 // #SchematycTODO : Ideally it should be the implementation that decides whether or not to serialize inputs and outputs.
756 case EScriptGraphType::Function
:
757 case EScriptGraphType::Condition
:
759 Serialization::SContext
fileContext(archive
, static_cast<IScriptFile
*>(&graph
.GetFile())); // #SchematycTODO : Do we still need this?
760 Serialization::SContext
docGraphContext(archive
, static_cast<CDocGraphBase
*>(&graph
)); // #SchematycTODO : Do we still need this?
761 archive(graph
.m_inputs
, "inputs", "Inputs");
762 archive(graph
.m_outputs
, "outputs", "Outputs");
768 //////////////////////////////////////////////////////////////////////////
769 CDocGraphBase::SNodeAndLinkSerializer::SNodeAndLinkSerializer(CDocGraphBase
& _graph
)
773 //////////////////////////////////////////////////////////////////////////
774 void CDocGraphBase::SNodeAndLinkSerializer::Serialize(Serialization::IArchive
& archive
)
776 Serialization::SContext
fileContext(archive
, static_cast<IScriptFile
*>(&graph
.GetFile())); // #SchematycTODO : Do we still need this?
777 Serialization::SContext
docGraphContext(archive
, static_cast<CDocGraphBase
*>(&graph
)); // #SchematycTODO : Do we still need this?
778 yasli::SerializeMapAsVector
<DocGraphNodeMap
, SGUID
, SDocGraphNode
>(archive
, graph
.m_nodes
, "nodes", "nodes");
780 std::sort(graph
.m_links
.begin(), graph
.m_links
.end(), [](const CScriptGraphLinkPtr a
, const CScriptGraphLinkPtr b
)
782 return a
->GetSrcNodeGUID() > b
->GetSrcNodeGUID();
785 archive(graph
.m_links
, "links");
788 //////////////////////////////////////////////////////////////////////////
789 CDocGraphBase::SAvailableNode::SAvailableNode(const char* _szName
, EScriptGraphNodeType _type
, const SGUID
& _contextGUID
, const SGUID
& _refGUID
)
792 , contextGUID(_contextGUID
)
796 //////////////////////////////////////////////////////////////////////////
797 bool CDocGraphBase::IsBrokenLink(const CScriptGraphLink
& link
) const
799 const IScriptGraphNode
* pSrcNode
= GetNode(link
.GetSrcNodeGUID());
800 if(!pSrcNode
|| (DocUtils::FindGraphNodeOutput(*pSrcNode
, link
.GetSrcOutputName()) == INVALID_INDEX
))
804 const IScriptGraphNode
* pDstNode
= GetNode(link
.GetDstNodeGUID());
805 if(!pDstNode
|| (DocUtils::FindGraphNodeInput(*pDstNode
, link
.GetDstInputName()) == INVALID_INDEX
))