ctkTestApp.cpp 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244
  1. /*=============================================================================
  2. Library: CTK
  3. Copyright (c) German Cancer Research Center,
  4. Division of Medical and Biological Informatics
  5. Licensed under the Apache License, Version 2.0 (the "License");
  6. you may not use this file except in compliance with the License.
  7. You may obtain a copy of the License at
  8. http://www.apache.org/licenses/LICENSE-2.0
  9. Unless required by applicable law or agreed to in writing, software
  10. distributed under the License is distributed on an "AS IS" BASIS,
  11. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. See the License for the specific language governing permissions and
  13. limitations under the License.
  14. =============================================================================*/
  15. #include "ctkTestApp_p.h"
  16. #include <ctkPluginContext.h>
  17. #include <service/application/ctkApplicationException.h>
  18. #include <QDebug>
  19. #include <QThread>
  20. #include <QCoreApplication>
  21. //----------------------------------------------------------------------------
  22. MyAppDescriptor::MyAppDescriptor(const QString& id, MyAppContainer* container)
  23. : id(id)
  24. , container(container)
  25. {
  26. }
  27. //----------------------------------------------------------------------------
  28. QString MyAppDescriptor::getApplicationId() const
  29. {
  30. return id;
  31. }
  32. //----------------------------------------------------------------------------
  33. ctkProperties MyAppDescriptor::getProperties(const QLocale&) const
  34. {
  35. return getProperties();
  36. }
  37. //----------------------------------------------------------------------------
  38. ctkProperties MyAppDescriptor::getProperties() const
  39. {
  40. ctkProperties props;
  41. props[ctkApplicationDescriptor::APPLICATION_PID] = getApplicationId();
  42. return props;
  43. }
  44. //----------------------------------------------------------------------------
  45. ctkApplicationHandle* MyAppDescriptor::launch(const QHash<QString, QVariant>& arguments)
  46. {
  47. MyAppHandle* appHandle = createAppHandle(arguments);
  48. container->launch(appHandle);
  49. return appHandle;
  50. }
  51. //----------------------------------------------------------------------------
  52. MyAppHandle* MyAppDescriptor::createAppHandle(const ctkProperties& /*arguments*/)
  53. {
  54. MyAppHandle* newAppHandle = new MyAppHandle(getInstanceId(), this);
  55. container->registerHandle(newAppHandle);
  56. return newAppHandle;
  57. }
  58. //----------------------------------------------------------------------------
  59. QString MyAppDescriptor::getInstanceId() const
  60. {
  61. static long instanceId = 0;
  62. return getApplicationId() + "." + QString::number(instanceId++);
  63. }
  64. //----------------------------------------------------------------------------
  65. MyAppHandle::MyAppHandle(const QString& instanceId, ctkApplicationDescriptor* descriptor)
  66. : descriptor(descriptor)
  67. , instanceId(instanceId)
  68. {
  69. }
  70. //----------------------------------------------------------------------------
  71. ctkApplicationDescriptor*MyAppHandle::getApplicationDescriptor() const
  72. {
  73. return descriptor;
  74. }
  75. //----------------------------------------------------------------------------
  76. QString MyAppHandle::getState() const
  77. {
  78. return "unknown";
  79. }
  80. //----------------------------------------------------------------------------
  81. QVariant MyAppHandle::getExitValue(long /*timeout*/) const
  82. {
  83. return QVariant();
  84. }
  85. //----------------------------------------------------------------------------
  86. QString MyAppHandle::getInstanceId() const
  87. {
  88. return instanceId;
  89. }
  90. //----------------------------------------------------------------------------
  91. void MyAppHandle::destroy()
  92. {
  93. }
  94. //----------------------------------------------------------------------------
  95. QVariant MyAppHandle::run(const QVariant& /*context*/)
  96. {
  97. Q_ASSERT_X(QThread::currentThread() == QCoreApplication::instance()->thread(), "MyAppHandle::run", "Not running in main thread");
  98. QCoreApplication::instance()->setProperty("app_test.success", true);
  99. return QVariant();
  100. }
  101. //----------------------------------------------------------------------------
  102. void MyAppHandle::stop()
  103. {
  104. }
  105. //----------------------------------------------------------------------------
  106. MyAppContainer::MyAppContainer(ctkPluginContext* context)
  107. : context(context)
  108. , appLauncher(NULL)
  109. , launcherTracker(context, this)
  110. , defaultMainThreadAppHandle(NULL)
  111. {
  112. }
  113. //----------------------------------------------------------------------------
  114. MyAppContainer::~MyAppContainer()
  115. {
  116. }
  117. //----------------------------------------------------------------------------
  118. void MyAppContainer::start()
  119. {
  120. qDebug() << "Starting app container";
  121. launcherTracker.open();
  122. // register a (default) test descriptor
  123. MyAppDescriptor* appDescr = new MyAppDescriptor("test-app", this);
  124. ctkServiceRegistration reg = context->registerService<ctkApplicationDescriptor>(appDescr, appDescr->getProperties());
  125. descriptorRegistrations.insert(appDescr, reg);
  126. descriptors.push_back(appDescr);
  127. try
  128. {
  129. appDescr->launch(ctkProperties());
  130. }
  131. catch (const ctkApplicationException& e)
  132. {
  133. qWarning() << "An error occurred whild starting the application:" << e;
  134. }
  135. }
  136. //----------------------------------------------------------------------------
  137. void MyAppContainer::stop()
  138. {
  139. for(QHash<MyAppHandle*, ctkServiceRegistration>::iterator iter = handleRegistrations.begin();
  140. iter != handleRegistrations.end(); ++iter)
  141. {
  142. iter.key()->destroy();
  143. iter.value().unregister();
  144. }
  145. qDeleteAll(handles);
  146. for(QHash<MyAppDescriptor*, ctkServiceRegistration>::iterator iter = descriptorRegistrations.begin();
  147. iter != descriptorRegistrations.end(); ++iter)
  148. {
  149. iter.value().unregister();
  150. }
  151. qDeleteAll(descriptors);
  152. launcherTracker.close();
  153. }
  154. //----------------------------------------------------------------------------
  155. void MyAppContainer::launch(MyAppHandle* handle)
  156. {
  157. // use the ApplicationLauncher provided by the framework to ensure it is launched on the main thread
  158. ctkApplicationLauncher* appLauncher = launcherTracker.getService();
  159. if (appLauncher == NULL)
  160. {
  161. // we need to wait to allow the ApplicationLauncher to get registered;
  162. // save the handle to be launched as soon as the ApplicationLauncher is available
  163. defaultMainThreadAppHandle = handle;
  164. qDebug() << "Waiting for AppLauncher to become available";
  165. return;
  166. }
  167. appLauncher->launch(handle, QVariant());
  168. }
  169. //----------------------------------------------------------------------------
  170. void MyAppContainer::registerHandle(MyAppHandle* handle)
  171. {
  172. ctkServiceRegistration reg = context->registerService<ctkApplicationHandle>(handle);
  173. handles.push_back(handle);
  174. handleRegistrations.insert(handle, reg);
  175. }
  176. ctkApplicationLauncher* MyAppContainer::addingService(const ctkServiceReference& reference)
  177. {
  178. ctkApplicationLauncher* appLauncher = NULL;
  179. ctkApplicationRunnable* appRunnable = NULL;
  180. appLauncher = context->getService<ctkApplicationLauncher>(reference);
  181. // see if there is a default main threaded application waiting to run
  182. appRunnable = defaultMainThreadAppHandle;
  183. // null out so we do not attempt to start this handle again
  184. defaultMainThreadAppHandle = NULL;
  185. if (appRunnable != NULL)
  186. {
  187. // found a main threaded app; start it now that the app launcher is available
  188. appLauncher->launch(appRunnable, QVariant());
  189. }
  190. return appLauncher;
  191. }
  192. //----------------------------------------------------------------------------
  193. void MyAppContainer::modifiedService(const ctkServiceReference&, ctkApplicationLauncher*)
  194. {
  195. }
  196. //----------------------------------------------------------------------------
  197. void MyAppContainer::removedService(const ctkServiceReference&, ctkApplicationLauncher*)
  198. {
  199. }