00001 #ifndef AppImpl_H_
00002 #define AppImpl_H_
00003
00004 #include "Log.h"
00005 #include "fv_threads.h"
00006 #include "fv_config.h"
00007 #include "pch_intf.h"
00008
00009 #include <unistd.h>
00010 #include <memory>
00011
00012 namespace FemViewer {
00013
00014
00015 enum InstantType {
00016 MODULE,
00017 APPLICATION
00018 };
00019
00020
00021 enum CoreType {
00022 ALONE = 0,
00023 MASTER,
00024 SLAVE,
00025 COUNT
00026 };
00027
00028
00029
00030 template< typename T,CoreType Type > struct Start;
00031
00032 int run_application(int argc, char** argv, bool initgl, Thread* parent = nullptr);
00033
00034 class ModuleThread : public Thread
00035 {
00036 public:
00037 int _shutdown;
00038 int _argc;
00039 char** _argv;
00040 bool _running;
00041
00042 explicit ModuleThread(int argc,char** argv);
00043 virtual ~ModuleThread();
00044
00045 int Check() const { return _shutdown; }
00046
00047 void Start();
00048 int Run();
00049 int Update();
00050 void Stop();
00051 };
00052
00053
00054 template<class T> class AppImpl
00055 {
00056 typedef T Core;
00057
00058 public:
00059
00060 static int run(int argc,char **argv)
00061 {
00062
00063 return Core::Init(argc,argv);
00064 }
00065 };
00066
00067
00068 template<class T>
00069 class AppImpl<T*>
00070 {
00071 typedef T Core;
00072
00073 public:
00074
00075 static int run(int argc,char** argv);
00076 static void close(void);
00077
00078 ModuleThread _thread;
00079 ~AppImpl() {}
00080
00081 protected:
00082 static std::unique_ptr<AppImpl<T*> > _self;
00083
00084 AppImpl(int argc,char** argv) : _thread(argc,argv) {
00085 mfp_log_debug("ctr of pointer types\n");
00086 atexit(close);
00087 }
00088
00089 private:
00090 AppImpl(const AppImpl&);
00091 void operator=(const AppImpl&);
00092 };
00093
00094
00095 template<class T>
00096 std::unique_ptr<AppImpl<T*> > AppImpl<T*>::_self;
00097
00098
00099 template< typename T >
00100 struct Start<T,ALONE> {
00101 static fv_thread_return run(void *pParams)
00102 {
00103 AppImpl<T*> * lptr = reinterpret_cast<AppImpl<T*> *>(pParams);
00104
00105 T::Init(lptr->_argc,lptr->_argv, lptr);
00106 ENTERCRITICALSECTION(lptr->_crtsec);
00107
00108
00109 fv_wakeup(&(lptr->_signal));
00110 LEAVECRITICALSECTION(lptr->_crtsec);
00111 lptr->destroy_self();
00112 return (fv_thread_return)0;
00113 }
00114 };
00115
00116
00117 template< typename T >
00118 struct Start<T,MASTER> {
00119 static fv_thread_return run(void *pParams) {
00120 AppImpl<T> * lptr = reinterpret_cast<AppImpl<T> *>(pParams);
00121 T::Init(lptr->_argc,lptr->_argv);
00122
00123 lptr->close();
00124 return (fv_thread_return)0;
00125 }
00126 };
00127
00128
00129 template< typename T >
00130 struct Start<T,SLAVE> {
00131 static fv_thread_return run(void *pParams) {
00132 AppImpl<T*> * lptr = static_cast<AppImpl<T*> *>(pParams);
00133 T::Init2(lptr->_argc,lptr->_argv);
00134
00135
00136 lptr->destroy_self();
00137 return (fv_thread_return)0;
00138 }
00139 };
00140
00141 #define NO_GUI 1
00142
00143 template<class T>
00144 int AppImpl<T*>::run(int argc, char **argv)
00145 {
00146 if (!_self.get())
00147 {
00148 try {
00149 mfp_log_debug("init graphics\n");
00150 _self.reset(new AppImpl<T*>(argc,argv));
00151 _self->_thread.Start();
00152 }
00153 catch (const std::bad_alloc & e) {
00154 std::string msg("Error during graphic application init: ");
00155 msg.append( e.what());
00156 throw msg.c_str();
00157 }
00158 }
00159 else {
00160 close();
00161 }
00162
00163
00164 return 0;
00165 }
00166
00167 template<class T>
00168 void AppImpl<T*>::close(void)
00169 {
00170 mfp_debug("close\n");
00171 if (_self.get() != nullptr && !(_self->_thread._shutdown))
00172 {
00173
00174 _self->_thread.Stop();
00175
00176
00177 ::sleep(100);
00178 mfp_debug("before releasing\n");
00179 _self.release();
00180 }
00181 }
00182
00183
00184 }
00185
00186 #endif