dfs
[qflow:andreahmeds-andreahmeds-dataflowcore.git] / Graph.cpp
1 /*
2  * Graph.cpp
3  *
4  *  Created on: Feb 5, 2011
5  *      Author: michal
6  */
7
8 #include "Graph.h"
9 #include <qobjectdefs.h>
10 #include <initiable.h>
11 #include <blocking.h>
12 #include <QMdiSubWindow>
13 #include <QFormLayout>
14 #include <QSizeGrip>
15 #include <exception>
16
17 Connection::Connection(Signal signal, Slot slot) :
18         _signal(signal), _slot(slot)
19 {
20
21 }
22
23 Signal Connection::signal()
24 {
25     return _signal;
26 }
27 Slot Connection::slot()
28 {
29     return _slot;
30 }
31
32 QList<LibraryInfo*>* Graph::getLibraries()
33 {
34         return libraries;
35 }
36 ErrorInfo Graph::lastError()
37 {
38     return _lastError;
39 }
40
41 Graph::Graph() : libraries(NULL), _mainWin(NULL),
42     _lastError(ErrorInfo())
43 {
44
45     LibraryLoader loader;
46     _lastError = loader.loadLibraries(&libraries);
47     foreach(LibraryInfo* info, *libraries)
48     {
49         foreach(const QMetaObject* meta, *info->Modules)
50         {
51             this->classRegister_Module.insert(meta->className(), ClassInfo(*meta));
52         }
53         foreach(const QMetaObject* meta, *info->DynamicSignals)
54         {
55             this->classRegister_Signal.insert(meta->className(), ClassInfo(*meta));
56         }
57         foreach(const QMetaObject* meta, *info->DynamicSlots)
58         {
59             this->classRegister_Slot.insert(meta->className(), ClassInfo(*meta));
60         }
61     }
62
63 }
64 void Graph::setMainWin(QWidget *mainWin)
65 {
66     _mainWin = mainWin;
67 }
68
69 void Graph::clear()
70 {
71     foreach(QObject* obj, connections.keys())
72     {
73         QString s = obj->objectName();
74         delete obj;
75     }
76     connections.clear();
77 }
78
79 Graph::~Graph() {
80     clear();
81 }
82
83 int Graph::objectCount(QString className)
84 {
85     return classRegister_Module[className].count();
86 }
87
88 void Graph::addObject(QObject* obj)
89 {
90     connections.insert(obj, ConnectionList());
91     classRegister_Module[obj->metaObject()->className()].incrementCount();
92 }
93
94 QObject* Graph::createObject(QString className)
95 {
96     if(classRegister_Module.contains(className))
97     {
98         QMetaObject meta = classRegister_Module[className].meta();
99         QObject* obj = meta.newInstance();
100         return obj;
101     }
102     else return NULL;
103 }
104 void Graph::removeObject(QObject* obj)
105 {
106     connections.remove(obj);
107     classRegister_Module[obj->metaObject()->className()].decrementCount();
108 }
109 bool Graph::connect(Signal signal, Slot slot)
110 {
111     QString signalT = QString("2%1").arg(signal.metaMethod().signature());
112     QString slotT = QString("1%1").arg(slot.metaMethod().signature());
113     bool res = QObject::connect(signal.methodOwner(), signalT.toAscii(), slot.methodOwner(), slotT.toAscii(), Qt::DirectConnection);
114     if(!res) return false;
115     Connection con(signal, slot);
116     connections[signal.owner()].push_back(con);
117     return true;
118 }
119 bool Graph::disconnect(Signal signal, Slot slot)
120 {
121     QString signalT = QString("2%1").arg(signal.metaMethod().signature());
122     QString slotT = QString("1%1").arg(slot.metaMethod().signature());
123     bool res = QObject::disconnect(signal.methodOwner(), signalT.toAscii(), slot.methodOwner(), slotT.toAscii());
124     int index = -1;
125     for(int i = 0; i<connections[signal.owner()].count();i++)
126     {
127         if(connections[signal.owner()][i].slot().name() == slot.name()) index = i;
128     }
129     if(index != -1) connections[signal.owner()].removeAt(index);
130     return res;
131 }
132
133 QHash<QObject*, ConnectionList>* Graph::Connections()
134 {
135     return &connections;
136 }
137 void Graph::closeWidgets()
138 {
139     foreach(QObject* obj, connections.keys())
140     {
141         QWidget* widget = qobject_cast<QWidget*>(obj);
142         if(widget)
143         {
144             widget->close();
145         }
146     }
147 }
148
149 void Graph::start()
150 {
151     _lastError = ErrorInfo();
152     QList<Initiable*> initialized;
153     foreach(QObject* obj, connections.keys())
154     {
155         Initiable* ini = dynamic_cast<Initiable*>(obj);
156         if(ini)
157         {
158             ErrorInfo err = ini->init();
159             if(err)
160             {
161                 _lastError = err;
162                 break;
163             }
164             initialized.push_back(ini);
165         }
166     }
167     if(_lastError)
168     {
169         foreach(Initiable* ini, initialized)
170         {
171             ini->deinit();
172         }
173         return;
174     }
175
176     if(_mainWin)
177     {
178         foreach(QObject* obj, connections.keys())
179         {
180             QWidget* widget = qobject_cast<QWidget*>(obj);
181             if(widget)
182             {
183                 widget->setParent(_mainWin);
184                 widget->show();
185             }
186         }
187     }
188
189     foreach(QObject* obj, connections.keys())
190     {
191         IStartable* startable = dynamic_cast<IStartable*>(obj);
192         if(startable)
193         {
194             WaitHandle handle = startable->startModule();
195             runningModules.insert(startable,handle);
196         }
197     }
198 }
199 void Graph::stop()
200 {
201     foreach(QObject* obj, connections.keys())
202     {
203         Blocking* blo = dynamic_cast<Blocking*>(obj);
204         if(blo)
205         {
206             blo->unblock();
207         }
208     }
209     foreach(IStartable* startable, runningModules.keys())
210     {
211         startable->stopModule();
212     }
213     foreach(WaitHandle handle, runningModules.values())
214     {
215         handle.wait();
216     }
217     runningModules.clear();
218
219     foreach(QObject* obj, connections.keys())
220     {
221         Initiable* ini = dynamic_cast<Initiable*>(obj);
222         if(ini)
223         {
224             ErrorInfo err = ini->deinit();
225             _lastError = err;
226             if(_lastError) return;
227         }
228     }
229 }