arcsprocess.cpp
1 /*
2  name: lib/arcsprocess.cpp
3 
4  This file is part of ARCS - Augmented Reality Component System
5  (version 2-current), written by Jean-Yves Didier
6  for IBISC Laboratory (http://www.ibisc.univ-evry.fr)
7 
8  Copyright (C) 2013 Université d'Evry-Val d'Essonne
9 
10  This program is free software: you can redistribute it and/or modify
11  it under the terms of the GNU General Public License as published by
12  the Free Software Foundation, either version 2 of the License, or
13  (at your option) any later version.
14 
15  This program is distributed in the hope that it will be useful,
16  but WITHOUT ANY WARRANTY; without even the implied warranty of
17  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18  GNU General Public License for more details.
19 
20  You should have received a copy of the GNU General Public License
21  along with this program. If not, see <http://www.gnu.org/licenses/>.
22 
23 
24  Please send bugreports with examples or suggestions to
25  jean-yves.didier__at__ibisc.univ-evry.fr
26 */
27 
28 
29 #include <arcs/arcsprocess.h>
30 #include <arcs/arcsappmode.h>
31 #include <arcs/arcscontrollercomponent.h>
32 
33 #include <QEvent>
34 #include <QMutex>
35 
36 ARCSProcess::ARCSProcess() : QObject()
37 {
38  controller = 0;
39  currentSheetId = QString::null;
40  applicationMode = 0;
41  processFinished = true;
42  mutex.lock();
43  firstTime = true;
44  mutex.unlock();
45  currentMode = ARCS::ARCS_APP_NONE;
46 }
47 
48 ARCSProcess::~ARCSProcess()
49 {
50 }
51 
53 {
54  if (flag == ARCS::ARCS_APP_EVENT || flag == ARCS::ARCS_APP_GUI || flag == ARCS::ARCS_APP_THREADEVENT)
55  currentMode = ARCS::ARCS_APP_THREADEVENT ;
56  else
57  currentMode = ARCS::ARCS_APP_THREAD;
58  setProcessMode();
59 }
60 
61 
62 bool ARCSProcess::event(QEvent* event)
63 {
64  if (event->type() == QEvent::ApplicationActivate || event->type() == ARCSAppEvent::eventType)
65  {
66  if (!processFinished)
68  return true;
69  }
70 
71  return QObject::event(event);
72 }
73 
74 
75 void ARCSProcess::changeSheet(QString s)
76 {
77  if (!sheets.contains(s))
78  {
79  std::cerr << "[Process] Sheet " << qPrintable(s) << " not found." << std::endl;
80  return ;
81  }
82 
83  if (!currentSheetId.isEmpty())
84  {
85  ARCSSheet& current = sheets[currentSheetId];
86  current.deactivate();
87  }
88 
89 
90  if (controller->getStateMachine()->hasFinished())
91  {
92  processFinished = true;
93  emit finished();
94  return;
95  }
96 
97  currentSheetId = s;
98 
99  mutex.lock();
100  if (firstTime)
101  {
102  firstTime = false;
103  if (currentMode == ARCS::ARCS_APP_THREAD || currentMode == ARCS::ARCS_APP_THREADEVENT)
104  cond.wakeAll();
105  }
106  mutex.unlock();
107 
108  applicationMode->tokenHook();
109 }
110 
111 
113 {
114  mutex.lock();
115  firstTime = true;
116  mutex.unlock();
117 }
118 
119 
121 {
122  // may be this is not necessary
123  /*if (s.isEmpty())
124  {
125  controllerId = s;
126  controller = 0;
127  return;
128  }*/
129 
130  ARCSAbstractComponent* aac = context->getComponent(s);
131  if (aac == 0)
132  return false;
133 
134  ARCSControllerComponent* ctrl = dynamic_cast<ARCSControllerComponent*>(aac);
135 
136  if (ctrl != 0)
137  {
138  controller = ctrl;
139  return true;
140  }
141 
142  return false;
143 }
144 
145 void ARCSProcess::setProcessMode()
146 {
147  if (applicationMode != 0)
148  delete applicationMode;
149 
150  switch(currentMode)
151  {
152  case ARCS::ARCS_APP_BASE:
153  applicationMode = new ARCSAppBase(this);
154  break;
156  applicationMode = new ARCSAppThread(this);
157  break;
159  applicationMode = new ARCSAppThreadEvent(this);
160  break;
161  case ARCS::ARCS_APP_GUI:
162  applicationMode = new ARCSAppGUI(this);
163  break;
164  default:
165  applicationMode = new ARCSAppEvent(this);
166  };
167 
168 }
169 
170 
171 
172 
174 {
175  processFinished = false;
176 
177  if (controller == 0)
178  {
179  std::cerr << "[Core] Process has not any controller" << std::endl;
180  return false;
181  }
182 
183  QObject::connect(controller->getStateMachine(), SIGNAL(sendSheet(QString)), this, SLOT(changeSheet(QString)),Qt::DirectConnection);
184  QObject::connect(controller->getStateMachine(), SIGNAL(finished()), this, SLOT(finish()),Qt::DirectConnection);
185  applicationMode->startHook();
186 
187  return true;
188 }
189 
190 
191 
193 {
194  mutex.lock();
195  firstTime = true;
196  mutex.unlock();
197  return true;
198 }
199 
200 
202 {
203  mutex.lock();
204  if (firstTime)
205  cond.wait(&mutex);
206  mutex.unlock();
207 }
208 
209 void ARCSProcess::addSheet(QString s, ARCSSheet sh)
210 {
211  sh.setContext(context);
212  sheets.insert(s, sh);
213 }
214 
215 
217 {
218  if (currentSheetId.isEmpty())
219  return ;
220 
221  if (!sheets.contains(currentSheetId))
222  {
223  std::cerr << "[Process] unknown sheet: " << qPrintable(currentSheetId) << std::endl;
224  return ;
225  }
226  ARCSSheet& sheet = sheets[currentSheetId];
227  if (!sheet.isActivated())
228  sheet.activate();
229 }
230 
231 
233 {
234  if (currentMode != ARCS::ARCS_APP_THREAD && currentMode != ARCS::ARCS_APP_THREADEVENT)
235  return ;
236 
237  if (applicationMode == NULL)
238  return ;
239 
240  QThread* threadToWaitFor = dynamic_cast<QThread*>(applicationMode);
241 
242  if (threadToWaitFor == NULL)
243  return ;
244 
245  threadToWaitFor->wait();
246 }
247 
248 void ARCSProcess::renameSheet(QString oldName, QString newName)
249 {
250  if (!sheets.contains(oldName))
251  return;
252  if ( sheets.contains(newName))
253  return;
254 
255  ARCSSheet sheet = sheets.take(oldName);
256  sheet.setName(newName);
257  addSheet(newName,sheet);
258 }
259 
261 {
262  if (sheets.contains(s))
263  sheets.remove(s);
264 }
void activate()
Definition: arcssheet.h:182
bool stopProcess()
void changeSheet(QString s)
Definition: arcsprocess.cpp:75
ARCSAppFlag
Flags to specify in which mode applications should start.
Definition: arcs.h:41
For applications running with Qt Widgets.
Definition: arcs.h:48
Threaded application handler.
Definition: arcsappmode.h:141
virtual void startHook()=0
Hook for starting applications Subclasses should reimplement this.
void renameSheet(QString oldName, QString newName)
void finished()
void deactivate()
Definition: arcssheet.h:184
void removeSheet(QString s)
bool startProcess()
None of the application mode has been selected so far.
Definition: arcs.h:43
bool setController(QString s=QString::null)
For applications nested in a thread.
Definition: arcs.h:46
Defines a controller component.
Class handling the generic description of a component.
virtual void tokenHook()=0
Hook for handling tokens Subclasses should reimplement this.
ARCSStateMachine * getStateMachine()
Event-loop based GUI application handler.
Definition: arcsappmode.h:115
ARCSAbstractComponent * getComponent(QString name)
Retrieves a component by its id.
Event-loop based application handler.
Definition: arcsappmode.h:92
bool isActivated()
Definition: arcssheet.h:241
virtual bool event(QEvent *event)
Definition: arcsprocess.cpp:62
void setupNextSheet()
void setName(QString s)
Definition: arcssheet.h:244
For applications nested in a thread running with an event loop.
Definition: arcs.h:47
Threaded and event-loop based application handler.
Definition: arcsappmode.h:158
For applications requiring event loops.
Definition: arcs.h:45
void setReferenceApplicationMode(ARCS::ARCSAppFlag flag)
Definition: arcsprocess.cpp:52
Maintains connections between objects.
Definition: arcssheet.h:48
For basic applications.
Definition: arcs.h:44
Basic application handler.
Definition: arcsappmode.h:77
void addSheet(QString s, ARCSSheet sh)
void waitForFirstSheet()