!B (Sandbox) (CE-21795) Importing models with multisubmaterials via fbx switches...
[CRYENGINE.git] / Code / CryEngine / CrySchematyc2 / Deprecated / DocGraphBase.cpp
blobb28184c56100df644359d053d31bd6cbc5e1d97d
1 // Copyright 2001-2019 Crytek GmbH / Crytek Group. All rights reserved.
3 #include "StdAfx.h"
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>
14 namespace Schematyc2
16 namespace DocGraphBaseUtils
18 struct SNodeHeader
20 inline SNodeHeader()
21 : type(EScriptGraphNodeType::Unknown)
22 , pos(ZERO)
25 inline SNodeHeader(const SGUID& _guid, EScriptGraphNodeType _type, const SGUID& _contextGUID, const SGUID& _refGUID, const Vec2& _pos)
26 : guid(_guid)
27 , type(_type)
28 , contextGUID(_contextGUID)
29 , refGUID(_refGUID)
30 , pos(_pos)
33 void Serialize(Serialization::IArchive& archive)
35 archive(guid, "guid");
36 archive(type, "type");
37 archive(contextGUID, "context_guid");
38 archive(refGUID, "ref_guid");
39 archive(pos, "pos");
42 SGUID guid;
43 EScriptGraphNodeType type;
44 SGUID contextGUID;
45 SGUID refGUID;
46 Vec2 pos;
49 struct SNodeMapValueSerializer
51 inline SNodeMapValueSerializer(std::pair<SGUID, SDocGraphNode>& _value)
52 : value(_value)
55 void Serialize(Serialization::IArchive& archive)
57 CDocGraphBase* pDocGraph = archive.context<CDocGraphBase>();
58 CRY_ASSERT(pDocGraph);
59 if(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);
75 return true;
78 /*inline bool Serialize(Serialization::IArchive& archive, shared_ptr<Schematyc2::CScriptGraphLink>& value, const char* szName, const char* szLabel)
80 if(!value)
82 value = std::make_shared<Schematyc2::CScriptGraphLink>();
84 archive(*value, szName, szLabel);
85 return true;
86 }*/
89 namespace Schematyc2
91 //////////////////////////////////////////////////////////////////////////
92 SDocGraphNode::SDocGraphNode() {}
94 //////////////////////////////////////////////////////////////////////////
95 SDocGraphNode::SDocGraphNode(const IScriptGraphNodePtr& _pNode)
96 : pNode(_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)
159 , m_guid(guid)
160 , m_scopeGUID(scopeGUID)
161 , m_name(szName)
162 , m_type(type)
163 , m_contextGUID(contextGUID)
164 , m_pos(ZERO)
167 //////////////////////////////////////////////////////////////////////////
168 SGUID CDocGraphBase::GetGUID() const
170 return m_guid;
173 //////////////////////////////////////////////////////////////////////////
174 SGUID CDocGraphBase::GetScopeGUID() const
176 return m_scopeGUID;
179 //////////////////////////////////////////////////////////////////////////
180 bool CDocGraphBase::SetName(const char* szName)
182 m_name = szName;
183 return true;
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);
196 if(enumerator)
198 if(m_contextGUID)
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);
220 RemoveBrokenLinks();
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");
242 break;
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");
248 break;
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");
259 break;
262 break;
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");
270 break;
272 case ESerializationPass::Save:
274 SInfoSerializer(*this).Serialize(archive);
275 SDataSerializer(*this).Serialize(archive);
276 SNodeAndLinkSerializer(*this).Serialize(archive);
277 break;
279 case ESerializationPass::Edit:
281 archive(m_name, "name", "!Name");
282 break;
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
310 return m_type;
313 //////////////////////////////////////////////////////////////////////////
314 SGUID CDocGraphBase::GetContextGUID() const
316 return m_contextGUID;
319 //////////////////////////////////////////////////////////////////////////
320 void CDocGraphBase::SetPos(Vec2 pos)
322 m_pos = pos;
325 //////////////////////////////////////////////////////////////////////////
326 Vec2 CDocGraphBase::GetPos() const
328 return m_pos;
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());
401 if(gEnv->IsEditor())
403 const SGUID guid = gEnv->pSchematyc2->CreateGUID();
404 if(!GetNode(guid))
406 IScriptGraphNodePtr pNode = CreateNode(guid, type, contextGUID, refGUID, pos);
407 CRY_ASSERT(pNode);
408 if(pNode)
410 m_nodes.insert(DocGraphNodeMap::value_type(guid, pNode));
411 return pNode.get();
415 return nullptr;
418 //////////////////////////////////////////////////////////////////////////
419 void CDocGraphBase::RemoveNode(const SGUID& guid)
421 IScriptGraphNode* pNode = GetNode(guid);
422 SCHEMATYC2_SYSTEM_ASSERT(pNode);
423 if(pNode)
425 m_nodes.erase(guid);
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);
447 if(visitor)
449 for(DocGraphNodeMap::value_type& node : m_nodes)
451 if(visitor(*node.second.pNode) != EVisitStatus::Continue)
453 return;
459 //////////////////////////////////////////////////////////////////////////
460 void CDocGraphBase::VisitNodes(const ScriptGraphNodeConstVisitor& visitor) const
462 SCHEMATYC2_SYSTEM_ASSERT(visitor);
463 if(visitor)
465 for(const DocGraphNodeMap::value_type& node : m_nodes)
467 if(visitor(*node.second.pNode) != EVisitStatus::Continue)
469 return;
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())
500 return false;
503 if((pDstNode->GetInputFlags(dstInputIdx) & EScriptGraphPortFlags::MultiLink) == 0)
505 TScriptGraphLinkConstVector dstInputLinks;
506 DocUtils::CollectGraphNodeInputLinks(*this, dstNodeGUID, pDstNode->GetInputName(dstInputIdx), dstInputLinks);
507 if(!dstInputLinks.empty())
509 return false;
512 if(CDocGraphBase::FindLink(srcNodeGUID, pSrcNode->GetOutputName(srcOutputIdx), dstNodeGUID, pDstNode->GetInputName(dstInputIdx)) != INVALID_INDEX)
514 return false;
516 // Trace back along sequence to make sure we're not creating a loop.
517 if(DocUtils::IsPrecedingNodeInGraphSequence(*this, *pSrcNode, dstNodeGUID))
519 return false;
521 return true;
525 return false;
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);
535 return pLink.get();
537 return nullptr;
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);
562 -- linkCount;
564 else
566 ++ 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);
611 if(visitor)
613 for(CScriptGraphLinkPtr& pLink : m_links)
615 if(visitor(*pLink) != EVisitStatus::Continue)
617 return;
623 //////////////////////////////////////////////////////////////////////////
624 void CDocGraphBase::VisitLinks(const ScriptGraphLinkConstVisitor& visitor) const
626 SCHEMATYC2_SYSTEM_ASSERT(visitor);
627 if(visitor)
629 for(const CScriptGraphLinkPtr& pLink : m_links)
631 if(visitor(*pLink) != EVisitStatus::Continue)
633 return;
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);
649 -- linkCount;
650 if(linkIdx < linkCount)
652 m_links[linkIdx] = m_links[linkCount];
655 else
657 ++ linkIdx;
660 m_links.resize(linkCount);
663 //////////////////////////////////////////////////////////////////////////
664 SScriptGraphSignals& CDocGraphBase::Signals()
666 return m_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);
682 if(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");
692 break;
694 case ESerializationPass::PostLoad:
696 archive(*value.second.pNode, "detail");
697 break;
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");
705 break;
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()
725 return m_inputs;
728 //////////////////////////////////////////////////////////////////////////
729 ScriptVariableDeclarationVector& CDocGraphBase::GetOutputs()
731 return m_outputs;
734 //////////////////////////////////////////////////////////////////////////
735 CDocGraphBase::SInfoSerializer::SInfoSerializer(CDocGraphBase& _graph)
736 : graph(_graph)
739 //////////////////////////////////////////////////////////////////////////
740 void CDocGraphBase::SInfoSerializer::Serialize(Serialization::IArchive& archive)
742 archive(graph.m_pos, "pos");
745 //////////////////////////////////////////////////////////////////////////
746 CDocGraphBase::SDataSerializer::SDataSerializer(CDocGraphBase& _graph)
747 : graph(_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.
754 switch(graph.m_type)
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");
763 break;
768 //////////////////////////////////////////////////////////////////////////
769 CDocGraphBase::SNodeAndLinkSerializer::SNodeAndLinkSerializer(CDocGraphBase& _graph)
770 : graph(_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)
790 : name(_szName)
791 , type(_type)
792 , contextGUID(_contextGUID)
793 , refGUID(_refGUID)
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))
802 return true;
804 const IScriptGraphNode* pDstNode = GetNode(link.GetDstNodeGUID());
805 if(!pDstNode || (DocUtils::FindGraphNodeInput(*pDstNode, link.GetDstInputName()) == INVALID_INDEX))
807 return true;
809 return false;