|
From: <ba...@us...> - 2008-11-28 20:26:13
|
Revision: 122
http://scstudio.svn.sourceforge.net/scstudio/?rev=122&view=rev
Author: babicaj
Date: 2008-11-28 20:26:06 +0000 (Fri, 28 Nov 2008)
Log Message:
-----------
Modified Paths:
--------------
trunk/src/check/msc_duplicators.cpp
trunk/src/data/msc.cpp
trunk/src/data/msc.h
Modified: trunk/src/check/msc_duplicators.cpp
===================================================================
--- trunk/src/check/msc_duplicators.cpp 2008-11-23 22:03:00 UTC (rev 121)
+++ trunk/src/check/msc_duplicators.cpp 2008-11-28 20:26:06 UTC (rev 122)
@@ -1,469 +1,469 @@
-/*
- * scstudio - Sequence Chart Studio
- * http://scstudio.sourceforge.net
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License version 2.1, as published by the Free Software Foundation.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * Copyright (c) 2008 Jindra Babica <ba...@ma...>
- *
- * $Id$
- */
+/*
+ * scstudio - Sequence Chart Studio
+ * http://scstudio.sourceforge.net
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * Copyright (c) 2008 Jindra Babica <ba...@ma...>
+ *
+ * $Id$
+ */
-#include "check/msc_duplicators.h"
-#include "check/dfs_instance_events_traverser.h"
-
-const std::string BMSC_DUPLICATOR_TRAVERSING_ATTR = "BDcolor";
-const std::string BMSC_DUPLICATOR_COPY_ATTR = "BDcopy";
-const std::string BMSC_GRAPH_DUPLICATOR_COPY_ATTR = "BGDcopy";
-const std::string BMSC_GRAPH_DUPLICATOR_REF_ATTR = "BGDreferencing";
-const std::string BMSC_GRAPH_DUPLICATOR_ENDLIST_ATTR = "BGDendlist";
-
-BMscDuplicator::BMscDuplicator()
-{
-}
-
-BMscPtr BMscDuplicator::duplicate_bmsc(BMscPtr &bmsc)
-{
- BMscPtr new_bmsc;
- if(bmsc.get())
- {
- new_bmsc = new BMsc(bmsc.get());
- DFSAreaTraverser traverser(BMSC_DUPLICATOR_TRAVERSING_ATTR);
- EventsCreatorListener events_creator(this,&traverser,new_bmsc.get());
- traverser.add_white_event_found_listener(&events_creator);
- traverser.add_black_event_found_listener(&events_creator);
- traverser.add_gray_event_found_listener(&events_creator);
- traverser.traverse(bmsc);
- traverser.remove_all_listeners();
- MessagesCreatorListener messages_creator(this);
- traverser.add_white_event_found_listener(&messages_creator);
- traverser.traverse(bmsc);
- }
- return new_bmsc;
-}
-
-Event*& BMscDuplicator::get_copy(Event* e)
-{
- bool just_set;
- Event*& copy = e->get_attribute<Event*>(BMSC_DUPLICATOR_COPY_ATTR,NULL,just_set);
- if(just_set)
- {
- m_modified_elements.push_back(e);
- }
- return copy;
-}
-
-BMscDuplicator::~BMscDuplicator()
-{
- EventPList::const_iterator i;
- for(i=m_modified_elements.begin();i!=m_modified_elements.end();i++)
- {
- (*i)->remove_attribute<Event*>(BMSC_DUPLICATOR_COPY_ATTR);
- }
-}
-
-BMscPtr BMscDuplicator::duplicate(BMscPtr& bmsc)
-{
- BMscDuplicator duplicator;
- return duplicator.duplicate_bmsc(bmsc);
-}
-
-EventsCreatorListener::EventsCreatorListener(BMscDuplicator* duplicator, DFSAreaTraverser* traverser, BMsc* bmsc):
- m_duplicator(duplicator),
- m_traverser(traverser),
- m_bmsc(bmsc),
- m_last_instance(NULL),
- m_last_area(NULL),
- m_last_new_instance(NULL),
- m_last_new_area(NULL)
-{
-
-}
-
-void EventsCreatorListener::on_white_event_found(Event* e)
-{
- if(m_last_instance!=e->get_instance())
- {
- InstancePtr new_instance = new Instance(e->get_instance());
- m_bmsc->add_instance(new_instance);
- m_last_instance = e->get_instance();
- m_last_new_instance = new_instance.get();
- }
- if(m_last_area!=e->get_general_area())
- {
- StrictOrderArea* strict = dynamic_cast<StrictOrderArea*>(e->get_general_area());
- EventAreaPtr area;
- if(strict)
- {
- area = new StrictOrderArea(strict);
- }
- else
- {
- area = new CoregionArea(dynamic_cast<CoregionArea*>(e->get_general_area()));
- }
- m_last_new_area = area.get();
- m_last_new_instance->add_area(area);
- m_last_area = e->get_general_area();
- }
- EventPtr new_event = m_last_new_area->add_event();
- new_event->set_original(e);
- Event*& copy = m_duplicator->get_copy(e);
- copy = new_event.get();
- create_successor(e);
-}
-
-CoregionEvent* EventsCreatorListener::get_preceding_event()
-{
- const MscElementPList& elements = m_traverser->get_reached_elements();
- if(elements.size()>1)
- {
- //in this case currently traversed event isn't alone in elements
- MscElementPList::const_iterator i = elements.end();
- i--; i--;
- return dynamic_cast<CoregionEvent*>(*i);
- }
- return NULL;
-}
-
-void EventsCreatorListener::on_gray_event_found(Event* e)
-{
- create_successor(e);
-}
-
-void EventsCreatorListener::on_black_event_found(Event* e)
-{
- create_successor(e);
-}
-
-void EventsCreatorListener::create_successor(Event* e)
-{
- CoregionEvent* coreg_new_event = dynamic_cast<CoregionEvent*>(e);
- if(coreg_new_event)
- {
- CoregionEvent* preceding = get_preceding_event();
- if(preceding)
- {
- preceding->add_successor(coreg_new_event);
- }
- }
-}
-
-MessagesCreatorListener::MessagesCreatorListener(BMscDuplicator* duplicator):
-m_duplicator(duplicator)
-{
-
-}
-
-void MessagesCreatorListener::on_white_event_found(Event* e)
-{
- Event* event_copy = m_duplicator->get_copy(e);
- if(e->is_matched())
- {
- if(e->is_send())
- {
- MscMessagePtr complete = new CompleteMessage(e,NULL,e->get_complete_message().get());
- event_copy->set_message(complete);
- Event* matching_copy = m_duplicator->get_copy(e->get_matching_event());
- matching_copy->set_message(complete);
- }
- }
- else
- {
- MscMessagePtr incomplete = new IncompleteMessage(e->get_incomplete_message().get());
- event_copy->set_message(incomplete);
- }
-}
-
-////////////////////////////////////////////////////////////////////////
-
-GraphCreatorListener::GraphCreatorListener(HMsc* hmsc):
-m_hmsc(hmsc)
-{
-}
-
-void GraphCreatorListener::on_white_node_found(HMscNode *n)
-{
- HMscNodePtr node;
- ReferenceNode* reference = dynamic_cast<ReferenceNode*>(n);
- if(reference)
- {
- on_white_node_found(reference);
- }
- else
- {
- ConnectionNode* connection = dynamic_cast<ConnectionNode*>(n);
- if(connection)
- {
- on_white_node_found(connection);
- }
- else
- {
- EndNode* end = dynamic_cast<EndNode*>(n);
- if(end)
- {
- on_white_node_found(end);
- }
- else
- {
- StartNode* start = dynamic_cast<StartNode*>(n);
- on_white_node_found(start);
- }
- }
- }
-}
-
-
-void GraphCreatorListener::on_white_node_found(ReferenceNode* n)
-{
- BMscPtr bmsc = n->get_bmsc();
- HMscNodePtr new_node;
- if(bmsc.get())
- {
- BMscPtr new_bmsc = BMscDuplicator::duplicate(bmsc);
- ReferenceNode* reference = new ReferenceNode(n);
- reference->set_msc(new_bmsc);
- new_node = reference;
- }
- else
- {
- ConnectionNode* connection = new ConnectionNode(n);
- new_node = connection;
- ReferenceNode*& attribute = get_referencing_node(n->get_hmsc().get());
- attribute = n;
- }
- process_new_node(n,new_node);
-}
-
-void GraphCreatorListener::on_white_node_found(StartNode* n)
-{
- if(is_root_element(n))
- {
- //in this case duplicated Startnode was already created
- m_new_nodes.push_back(m_hmsc->get_start().get());
- set_copy(n,m_hmsc->get_start().get());
- }
-}
-
-void GraphCreatorListener::on_white_node_found(EndNode* n)
-{
- HMscNodePtr new_node;
- if(is_root_element(n))
- {
- EndNode* end = new EndNode(n);
- new_node = end;
- }
- else
- {
- ConnectionNode* connection = new ConnectionNode(n);
- new_node = connection;
- add_to_end_list(connection);
- }
- process_new_node(n,new_node);
-}
-
-ConnectionNodePList& GraphCreatorListener::get_end_list(ReferenceNode* reference)
-{
- static ConnectionNodePList empty;
- //attribute is removed when reference is finished in traversing
- return reference->get_attribute<ConnectionNodePList>(BMSC_GRAPH_DUPLICATOR_ENDLIST_ATTR,empty);
-}
-
-void GraphCreatorListener::add_to_end_list(ConnectionNode* new_end)
-{
- HMsc* original_hmsc = new_end->get_original()->get_owner();
- ReferenceNode* original_reference = get_referencing_node(original_hmsc);
- ConnectionNodePList& end_list = get_end_list(original_reference);
- end_list.push_back(new_end);
-}
-
-void GraphCreatorListener::on_white_node_found(ConnectionNode* n)
-{
- PredecessorNode* predecessor = get_predecessor();
- HMscNodePtr new_node = new ConnectionNode(n);
- process_new_node(n,new_node);
-}
-
-void GraphCreatorListener::process_new_node(HMscNode* old_node, HMscNodePtr& new_node)
-{
- m_hmsc->add_node(new_node);
- add_new_successor(new_node.get());
- m_new_nodes.push_back(new_node.get());
- set_copy(old_node,new_node.get());
-}
-
-bool GraphCreatorListener::is_root_element(HMscNode* n)
-{
- return n->get_owner()==m_hmsc->get_original();
-}
-
-void GraphCreatorListener::set_copy(HMscNode* n, HMscNode* copy)
-{
- HMscNode*& attribute = get_copy(n);
- attribute = copy;
-}
-
-HMscNode*& GraphCreatorListener::get_copy(HMscNode* n)
-{
- bool just_set;
- HMscNode*& copy = n->get_attribute<HMscNode*>(BMSC_DUPLICATOR_COPY_ATTR,NULL,just_set);
- if(just_set)
- {
- m_modified_elements.push_back(n);
- }
- return copy;
-}
-
-PredecessorNode* GraphCreatorListener::get_predecessor()
-{
- return dynamic_cast<PredecessorNode*>(m_new_nodes.back());
-}
-
-void GraphCreatorListener::process_nonwhite_node(HMscNode* n)
-{
- HMscNode* copy = get_copy(n);
- add_new_successor(copy);
-}
-
-void GraphCreatorListener::on_gray_node_found(HMscNode* n)
-{
- process_nonwhite_node(n);
-}
-
-void GraphCreatorListener::on_black_node_found(HMscNode* n)
-{
- process_nonwhite_node(n);
-}
-
-void GraphCreatorListener::on_node_finished(HMscNode* n)
-{
- HMscNodePtr node;
- ReferenceNode* reference = dynamic_cast<ReferenceNode*>(n);
- if(reference)
- {
- on_node_finished(reference);
- }
- else
- {
- ConnectionNode* connection = dynamic_cast<ConnectionNode*>(n);
- if(connection)
- {
- on_node_finished(connection);
- }
- else
- {
- EndNode* end = dynamic_cast<EndNode*>(n);
- if(end)
- {
- on_node_finished(end);
- }
- else
- {
- StartNode* start = dynamic_cast<StartNode*>(n);
- on_node_finished(start);
- }
- }
- }
-}
-
-void GraphCreatorListener::on_node_finished(ReferenceNode* n)
-{
- n->remove_attribute<ConnectionNodePList>(BMSC_GRAPH_DUPLICATOR_ENDLIST_ATTR);
- m_new_nodes.pop_back();
-}
-
-void GraphCreatorListener::on_node_finished(StartNode* n)
-{
- if(is_root_element(n))
- {
- m_new_nodes.pop_back();
- }
-}
-
-void GraphCreatorListener::on_node_finished(EndNode* n)
-{
- m_new_nodes.pop_back();
-}
-
-void GraphCreatorListener::on_node_finished(ConnectionNode* n)
-{
- m_new_nodes.pop_back();
-}
-
-ReferenceNode*& GraphCreatorListener::get_referencing_node(HMsc* hmsc)
-{
- bool just_set;
- ReferenceNode*& reference = hmsc->get_attribute<ReferenceNode*>(BMSC_GRAPH_DUPLICATOR_REF_ATTR,NULL,just_set);
- if(just_set)
- {
- m_modified_hmscs.push_back(hmsc);
- }
- return reference;
-}
-
-void GraphCreatorListener::add_new_successor(HMscNode* new_successor)
-{
- SuccessorNode* new_succ = dynamic_cast<SuccessorNode*>(new_successor);
- PredecessorNode* predecessor = get_predecessor();
- ConnectionNode* connection = dynamic_cast<ConnectionNode*>(predecessor);
- if(connection)
- {
- ReferenceNode* original_reference = dynamic_cast<ReferenceNode*>(connection->get_original());
- if(original_reference &&
- new_successor->get_original()->get_owner()==original_reference->get_owner())
- {
- //connection was transformed from ReferenceNode and probably contains end_list,
- //elements of the end_list must become predecessors of new_successor which
- //must be from same HMsc as original_reference
- ConnectionNodePList& end_list = get_end_list(original_reference);
- ConnectionNodePList::const_iterator i;
- for(i=end_list.begin();i!=end_list.end();i++)
- {
- (*i)->add_successor(new_succ);
- }
- return;
- }
- }
- predecessor->add_successor(new_succ);
-}
-
-GraphCreatorListener::~GraphCreatorListener()
-{
- while(!m_modified_elements.empty())
- {
- MscElement* e = m_modified_elements.back();
- e->remove_attribute<HMscNode*>(BMSC_DUPLICATOR_COPY_ATTR);
- m_modified_elements.pop_back();
- }
- while(!m_modified_hmscs.empty())
- {
- HMsc* h = m_modified_hmscs.back();
- h->remove_attribute<ReferenceNode*>(BMSC_GRAPH_DUPLICATOR_REF_ATTR);
- m_modified_hmscs.pop_back();
- }
-}
-
-HMscPtr BMscGraphDuplicator::duplicate(HMscPtr& hmsc)
-{
- HMscPtr new_hmsc;
- if(hmsc.get())
- {
- new_hmsc = new HMsc(hmsc.get());
- GraphCreatorListener listener(new_hmsc.get());
- DFSBMscGraphTraverser traverser;
- traverser.add_black_node_found_listener(&listener);
- traverser.add_gray_node_found_listener(&listener);
- traverser.add_node_finished_listener(&listener);
- traverser.add_white_node_found_listener(&listener);
- traverser.traverse(hmsc);
- }
- return new_hmsc;
-}
-
-
+#include "check/msc_duplicators.h"
+#include "check/dfs_instance_events_traverser.h"
+
+const std::string BMSC_DUPLICATOR_TRAVERSING_ATTR = "BDcolor";
+const std::string BMSC_DUPLICATOR_COPY_ATTR = "BDcopy";
+const std::string BMSC_GRAPH_DUPLICATOR_COPY_ATTR = "BGDcopy";
+const std::string BMSC_GRAPH_DUPLICATOR_REF_ATTR = "BGDreferencing";
+const std::string BMSC_GRAPH_DUPLICATOR_ENDLIST_ATTR = "BGDendlist";
+
+BMscDuplicator::BMscDuplicator()
+{
+}
+
+BMscPtr BMscDuplicator::duplicate_bmsc(BMscPtr &bmsc)
+{
+ BMscPtr new_bmsc;
+ if(bmsc.get())
+ {
+ new_bmsc = new BMsc(bmsc.get());
+ DFSAreaTraverser traverser(BMSC_DUPLICATOR_TRAVERSING_ATTR);
+ EventsCreatorListener events_creator(this,&traverser,new_bmsc.get());
+ traverser.add_white_event_found_listener(&events_creator);
+ traverser.add_black_event_found_listener(&events_creator);
+ traverser.add_gray_event_found_listener(&events_creator);
+ traverser.traverse(bmsc);
+ traverser.remove_all_listeners();
+ MessagesCreatorListener messages_creator(this);
+ traverser.add_white_event_found_listener(&messages_creator);
+ traverser.traverse(bmsc);
+ }
+ return new_bmsc;
+}
+
+Event*& BMscDuplicator::get_copy(Event* e)
+{
+ bool just_set;
+ Event*& copy = e->get_attribute<Event*>(BMSC_DUPLICATOR_COPY_ATTR,NULL,just_set);
+ if(just_set)
+ {
+ m_modified_elements.push_back(e);
+ }
+ return copy;
+}
+
+BMscDuplicator::~BMscDuplicator()
+{
+ EventPList::const_iterator i;
+ for(i=m_modified_elements.begin();i!=m_modified_elements.end();i++)
+ {
+ (*i)->remove_attribute<Event*>(BMSC_DUPLICATOR_COPY_ATTR);
+ }
+}
+
+BMscPtr BMscDuplicator::duplicate(BMscPtr& bmsc)
+{
+ BMscDuplicator duplicator;
+ return duplicator.duplicate_bmsc(bmsc);
+}
+
+EventsCreatorListener::EventsCreatorListener(BMscDuplicator* duplicator, DFSAreaTraverser* traverser, BMsc* bmsc):
+ m_duplicator(duplicator),
+ m_traverser(traverser),
+ m_bmsc(bmsc),
+ m_last_instance(NULL),
+ m_last_area(NULL),
+ m_last_new_instance(NULL),
+ m_last_new_area(NULL)
+{
+
+}
+
+void EventsCreatorListener::on_white_event_found(Event* e)
+{
+ if(m_last_instance!=e->get_instance())
+ {
+ InstancePtr new_instance = new Instance(e->get_instance());
+ m_bmsc->add_instance(new_instance);
+ m_last_instance = e->get_instance();
+ m_last_new_instance = new_instance.get();
+ }
+ if(m_last_area!=e->get_general_area())
+ {
+ StrictOrderArea* strict = dynamic_cast<StrictOrderArea*>(e->get_general_area());
+ EventAreaPtr area;
+ if(strict)
+ {
+ area = new StrictOrderArea(strict);
+ }
+ else
+ {
+ area = new CoregionArea(dynamic_cast<CoregionArea*>(e->get_general_area()));
+ }
+ m_last_new_area = area.get();
+ m_last_new_instance->add_area(area);
+ m_last_area = e->get_general_area();
+ }
+ EventPtr new_event = m_last_new_area->add_event();
+ new_event->set_original(e);
+ Event*& copy = m_duplicator->get_copy(e);
+ copy = new_event.get();
+ create_successor(e);
+}
+
+CoregionEvent* EventsCreatorListener::get_preceding_event()
+{
+ const MscElementPList& elements = m_traverser->get_reached_elements();
+ if(elements.size()>1)
+ {
+ //in this case currently traversed event isn't alone in elements
+ MscElementPList::const_iterator i = elements.end();
+ i--; i--;
+ return dynamic_cast<CoregionEvent*>(*i);
+ }
+ return NULL;
+}
+
+void EventsCreatorListener::on_gray_event_found(Event* e)
+{
+ create_successor(e);
+}
+
+void EventsCreatorListener::on_black_event_found(Event* e)
+{
+ create_successor(e);
+}
+
+void EventsCreatorListener::create_successor(Event* e)
+{
+ CoregionEvent* coreg_new_event = dynamic_cast<CoregionEvent*>(e);
+ if(coreg_new_event)
+ {
+ CoregionEvent* preceding = get_preceding_event();
+ if(preceding)
+ {
+ preceding->add_successor(coreg_new_event);
+ }
+ }
+}
+
+MessagesCreatorListener::MessagesCreatorListener(BMscDuplicator* duplicator):
+m_duplicator(duplicator)
+{
+
+}
+
+void MessagesCreatorListener::on_white_event_found(Event* e)
+{
+ Event* event_copy = m_duplicator->get_copy(e);
+ if(e->is_matched())
+ {
+ if(e->is_send())
+ {
+ MscMessagePtr complete = new CompleteMessage(e,NULL,e->get_complete_message().get());
+ event_copy->set_message(complete);
+ Event* matching_copy = m_duplicator->get_copy(e->get_matching_event());
+ matching_copy->set_message(complete);
+ }
+ }
+ else
+ {
+ MscMessagePtr incomplete = new IncompleteMessage(e->get_incomplete_message().get());
+ event_copy->set_message(incomplete);
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+
+GraphCreatorListener::GraphCreatorListener(HMsc* hmsc):
+m_hmsc(hmsc)
+{
+}
+
+void GraphCreatorListener::on_white_node_found(HMscNode *n)
+{
+ HMscNodePtr node;
+ ReferenceNode* reference = dynamic_cast<ReferenceNode*>(n);
+ if(reference)
+ {
+ on_white_node_found(reference);
+ }
+ else
+ {
+ ConnectionNode* connection = dynamic_cast<ConnectionNode*>(n);
+ if(connection)
+ {
+ on_white_node_found(connection);
+ }
+ else
+ {
+ EndNode* end = dynamic_cast<EndNode*>(n);
+ if(end)
+ {
+ on_white_node_found(end);
+ }
+ else
+ {
+ StartNode* start = dynamic_cast<StartNode*>(n);
+ on_white_node_found(start);
+ }
+ }
+ }
+}
+
+
+void GraphCreatorListener::on_white_node_found(ReferenceNode* n)
+{
+ BMscPtr bmsc = n->get_bmsc();
+ HMscNodePtr new_node;
+ if(bmsc.get())
+ {
+ BMscPtr new_bmsc = BMscDuplicator::duplicate(bmsc);
+ ReferenceNode* reference = new ReferenceNode(n);
+ reference->set_msc(new_bmsc);
+ new_node = reference;
+ }
+ else
+ {
+ ConnectionNode* connection = new ConnectionNode(n);
+ new_node = connection;
+ ReferenceNode*& attribute = get_referencing_node(n->get_hmsc().get());
+ attribute = n;
+ }
+ process_new_node(n,new_node);
+}
+
+void GraphCreatorListener::on_white_node_found(StartNode* n)
+{
+ if(is_root_element(n))
+ {
+ //in this case duplicated Startnode was already created
+ m_new_nodes.push_back(m_hmsc->get_start().get());
+ set_copy(n,m_hmsc->get_start().get());
+ }
+}
+
+void GraphCreatorListener::on_white_node_found(EndNode* n)
+{
+ HMscNodePtr new_node;
+ if(is_root_element(n))
+ {
+ EndNode* end = new EndNode(n);
+ new_node = end;
+ }
+ else
+ {
+ ConnectionNode* connection = new ConnectionNode(n);
+ new_node = connection;
+ add_to_end_list(connection);
+ }
+ process_new_node(n,new_node);
+}
+
+ConnectionNodePList& GraphCreatorListener::get_end_list(ReferenceNode* reference)
+{
+ static ConnectionNodePList empty;
+ //attribute is removed when reference is finished in traversing
+ return reference->get_attribute<ConnectionNodePList>(BMSC_GRAPH_DUPLICATOR_ENDLIST_ATTR,empty);
+}
+
+void GraphCreatorListener::add_to_end_list(ConnectionNode* new_end)
+{
+ HMsc* original_hmsc = new_end->get_original()->get_owner();
+ ReferenceNode* original_reference = get_referencing_node(original_hmsc);
+ ConnectionNodePList& end_list = get_end_list(original_reference);
+ end_list.push_back(new_end);
+}
+
+void GraphCreatorListener::on_white_node_found(ConnectionNode* n)
+{
+ PredecessorNode* predecessor = get_predecessor();
+ HMscNodePtr new_node = new ConnectionNode(n);
+ process_new_node(n,new_node);
+}
+
+void GraphCreatorListener::process_new_node(HMscNode* old_node, HMscNodePtr& new_node)
+{
+ m_hmsc->add_node(new_node);
+ add_new_successor(new_node.get());
+ m_new_nodes.push_back(new_node.get());
+ set_copy(old_node,new_node.get());
+}
+
+bool GraphCreatorListener::is_root_element(HMscNode* n)
+{
+ return n->get_owner()==m_hmsc->get_original();
+}
+
+void GraphCreatorListener::set_copy(HMscNode* n, HMscNode* copy)
+{
+ HMscNode*& attribute = get_copy(n);
+ attribute = copy;
+}
+
+HMscNode*& GraphCreatorListener::get_copy(HMscNode* n)
+{
+ bool just_set;
+ HMscNode*& copy = n->get_attribute<HMscNode*>(BMSC_DUPLICATOR_COPY_ATTR,NULL,just_set);
+ if(just_set)
+ {
+ m_modified_elements.push_back(n);
+ }
+ return copy;
+}
+
+PredecessorNode* GraphCreatorListener::get_predecessor()
+{
+ return dynamic_cast<PredecessorNode*>(m_new_nodes.back());
+}
+
+void GraphCreatorListener::process_nonwhite_node(HMscNode* n)
+{
+ HMscNode* copy = get_copy(n);
+ add_new_successor(copy);
+}
+
+void GraphCreatorListener::on_gray_node_found(HMscNode* n)
+{
+ process_nonwhite_node(n);
+}
+
+void GraphCreatorListener::on_black_node_found(HMscNode* n)
+{
+ process_nonwhite_node(n);
+}
+
+void GraphCreatorListener::on_node_finished(HMscNode* n)
+{
+ HMscNodePtr node;
+ ReferenceNode* reference = dynamic_cast<ReferenceNode*>(n);
+ if(reference)
+ {
+ on_node_finished(reference);
+ }
+ else
+ {
+ ConnectionNode* connection = dynamic_cast<ConnectionNode*>(n);
+ if(connection)
+ {
+ on_node_finished(connection);
+ }
+ else
+ {
+ EndNode* end = dynamic_cast<EndNode*>(n);
+ if(end)
+ {
+ on_node_finished(end);
+ }
+ else
+ {
+ StartNode* start = dynamic_cast<StartNode*>(n);
+ on_node_finished(start);
+ }
+ }
+ }
+}
+
+void GraphCreatorListener::on_node_finished(ReferenceNode* n)
+{
+ n->remove_attribute<ConnectionNodePList>(BMSC_GRAPH_DUPLICATOR_ENDLIST_ATTR);
+ m_new_nodes.pop_back();
+}
+
+void GraphCreatorListener::on_node_finished(StartNode* n)
+{
+ if(is_root_element(n))
+ {
+ m_new_nodes.pop_back();
+ }
+}
+
+void GraphCreatorListener::on_node_finished(EndNode* n)
+{
+ m_new_nodes.pop_back();
+}
+
+void GraphCreatorListener::on_node_finished(ConnectionNode* n)
+{
+ m_new_nodes.pop_back();
+}
+
+ReferenceNode*& GraphCreatorListener::get_referencing_node(HMsc* hmsc)
+{
+ bool just_set;
+ ReferenceNode*& reference = hmsc->get_attribute<ReferenceNode*>(BMSC_GRAPH_DUPLICATOR_REF_ATTR,NULL,just_set);
+ if(just_set)
+ {
+ m_modified_hmscs.push_back(hmsc);
+ }
+ return reference;
+}
+
+void GraphCreatorListener::add_new_successor(HMscNode* new_successor)
+{
+ SuccessorNode* new_succ = dynamic_cast<SuccessorNode*>(new_successor);
+ PredecessorNode* predecessor = get_predecessor();
+ ConnectionNode* connection = dynamic_cast<ConnectionNode*>(predecessor);
+ if(connection)
+ {
+ ReferenceNode* original_reference = dynamic_cast<ReferenceNode*>(connection->get_original());
+ if(original_reference &&
+ new_successor->get_original()->get_owner()==original_reference->get_owner())
+ {
+ //connection was transformed from ReferenceNode and probably contains end_list,
+ //elements of the end_list must become predecessors of new_successor which
+ //must be from same HMsc as original_reference
+ ConnectionNodePList& end_list = get_end_list(original_reference);
+ ConnectionNodePList::const_iterator i;
+ for(i=end_list.begin();i!=end_list.end();i++)
+ {
+ (*i)->add_successor(new_succ);
+ }
+ return;
+ }
+ }
+ predecessor->add_successor(new_succ);
+}
+
+GraphCreatorListener::~GraphCreatorListener()
+{
+ while(!m_modified_elements.empty())
+ {
+ MscElement* e = m_modified_elements.back();
+ e->remove_attribute<HMscNode*>(BMSC_DUPLICATOR_COPY_ATTR);
+ m_modified_elements.pop_back();
+ }
+ while(!m_modified_hmscs.empty())
+ {
+ HMsc* h = m_modified_hmscs.back();
+ h->remove_attribute<ReferenceNode*>(BMSC_GRAPH_DUPLICATOR_REF_ATTR);
+ m_modified_hmscs.pop_back();
+ }
+}
+
+HMscPtr BMscGraphDuplicator::duplicate(HMscPtr& hmsc)
+{
+ HMscPtr new_hmsc;
+ if(hmsc.get())
+ {
+ new_hmsc = new HMsc(hmsc.get());
+ GraphCreatorListener listener(new_hmsc.get());
+ DFSBMscGraphTraverser traverser;
+ traverser.add_black_node_found_listener(&listener);
+ traverser.add_gray_node_found_listener(&listener);
+ traverser.add_node_finished_listener(&listener);
+ traverser.add_white_node_found_listener(&listener);
+ traverser.traverse(hmsc);
+ }
+ return new_hmsc;
+}
+
+
Modified: trunk/src/data/msc.cpp
===================================================================
--- trunk/src/data/msc.cpp 2008-11-23 22:03:00 UTC (rev 121)
+++ trunk/src/data/msc.cpp 2008-11-28 20:26:06 UTC (rev 122)
@@ -73,6 +73,10 @@
node->set_owner(this);
}
+void HMsc::remode_node(HMscNode* node)
+{
+}
+
////////////////////////////////////
/*inline StrictOrderArea* StrictEvent::get_strict_order_area()
Modified: trunk/src/data/msc.h
===================================================================
--- trunk/src/data/msc.h 2008-11-23 22:03:00 UTC (rev 121)
+++ trunk/src/data/msc.h 2008-11-28 20:26:06 UTC (rev 122)
@@ -691,6 +691,8 @@
}
void add_node(HMscNodePtr node);
+
+ void remode_node(HMscNode* node);
void remove_node(HMscNodePtr node)
{
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|