made mainloop pluggable and added qtmainloop plugin
authorKevron Rees <tripzero.kev@gmail.com>
Thu, 28 Feb 2013 22:06:59 +0000 (14:06 -0800)
committerKevron Rees <tripzero.kev@gmail.com>
Thu, 28 Feb 2013 22:06:59 +0000 (14:06 -0800)
13 files changed:
ambd/CMakeLists.txt
ambd/glibmainloop.cpp [new file with mode: 0644]
ambd/glibmainloop.h [new file with mode: 0644]
ambd/imainloop.h [new file with mode: 0644]
ambd/main.cpp
ambd/pluginloader.cpp
ambd/pluginloader.h
ambd/qtmainloop.cpp [new file with mode: 0644]
ambd/qtmainloop.h [new file with mode: 0644]
examples/qtmainloopconfig [new file with mode: 0644]
lib/vehicleproperty.cpp
plugins/CMakeLists.txt
plugins/dbus/parking.h

index b04402f..08ee300 100644 (file)
@@ -1,4 +1,18 @@
-add_executable(ambd core.cpp main.cpp pluginloader.cpp)
+set(ambd_headers core.h imainloop.h pluginloader.h glibmainloop.h)
+set(ambd_sources core.cpp main.cpp pluginloader.cpp glibmainloop.cpp)
+
+if(use_qtcore)
+    set(qtmainloopplugin_headers qtmainloop.h)
+    set(qtmainloopplugin_sources qtmainloop.cpp)
+
+    add_library(qtmainloopplugin MODULE ${qtmainloopplugin_sources})
+    set_target_properties(qtmainloopplugin PROPERTIES PREFIX "")
+    target_link_libraries(qtmainloopplugin amb -L${CMAKE_CURRENT_BINARY_DIR}/lib ${link_libraries})
+
+    install(TARGETS qtmainloopplugin LIBRARY DESTINATION lib/automotive-message-broker)
+endif(use_qtcore)
+
+add_executable(ambd ${ambd_sources})
 
 include_directories(${include_dirs} )
 target_link_libraries(ambd ${link_libraries} amb)
diff --git a/ambd/glibmainloop.cpp b/ambd/glibmainloop.cpp
new file mode 100644 (file)
index 0000000..b568cf2
--- /dev/null
@@ -0,0 +1,21 @@
+#include "glibmainloop.h"
+#include <glib.h>
+#include <stdlib.h>
+
+GlibMainLoop::GlibMainLoop(int argc, char **argv)
+       :IMainLoop(argc,argv)
+{
+       mainLoop = g_main_loop_new(NULL, false);
+}
+
+GlibMainLoop::~GlibMainLoop()
+{
+       g_main_loop_quit(mainLoop);
+       exit(0);
+}
+
+int GlibMainLoop::exec()
+{
+       g_main_loop_run(mainLoop);
+}
+
diff --git a/ambd/glibmainloop.h b/ambd/glibmainloop.h
new file mode 100644 (file)
index 0000000..547e432
--- /dev/null
@@ -0,0 +1,21 @@
+#ifndef _GLIBMAINLOOP_H_
+#define _GLIBMAINLOOP_H_
+
+#include "imainloop.h"
+#include <glib.h>
+
+class GlibMainLoop: public IMainLoop
+{
+public:
+
+       GlibMainLoop(int argc, char** argv);
+       ~GlibMainLoop();
+
+       int exec();
+
+private:
+       GMainLoop* mainLoop;
+};
+
+
+#endif
diff --git a/ambd/imainloop.h b/ambd/imainloop.h
new file mode 100644 (file)
index 0000000..9bcdc1b
--- /dev/null
@@ -0,0 +1,25 @@
+#ifndef IMAINLOOP_H_
+#define IMAINLOOP_H_
+
+
+
+class IMainLoop {
+public:
+
+       IMainLoop(int argc, char **argv)
+               :mArgc(argc),mArgv(argv)
+       {
+
+       }
+
+       virtual ~IMainLoop() { }
+
+       virtual int exec() = 0;
+
+private:
+       int mArgc;
+       char** mArgv;
+};
+
+
+#endif
index a978618..b2dadd7 100644 (file)
@@ -49,23 +49,15 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 
 using namespace std;
 
-#ifndef USE_QT_CORE
-
-GMainLoop* mainLoop = nullptr;
-
-#endif
+IMainLoop* mainloop = nullptr;
 
 void interrupt(int sign)
 {
        signal(sign, SIG_IGN);
        cout<<"Signal caught. Exiting gracefully.\n"<<endl;
        
-#ifdef USE_QT_CORE
-       QCoreApplication::exit(0);
-#else
-       g_main_loop_quit(mainLoop);
-       exit(0);
-#endif
+       /// this will cause the application to terminate and clean up:
+       delete mainloop;
 }
 
 void daemonize();
@@ -135,43 +127,24 @@ int main(int argc, char **argv)
                DebugOut::setOutput(logfile);
        }
 
-       
-#ifdef USE_QT_CORE
-
-       QCoreApplication app(argc,argv);
-
-#else
-
-       mainLoop = g_main_loop_new(NULL, false);
-       
-#endif
-       
        g_type_init();
 
        VehicleProperty::factory();
-
-       /* Register signal handler */
-       signal(SIGINT, interrupt);
-       signal(SIGTERM, interrupt);
        
-       PluginLoader loader(config, new Core());
+       PluginLoader loader(config, new Core(), argc, argv);
        
        if(!loader.sources().size())
        {
                throw std::runtime_error("No sources present. aborting");
        }
-       
-       
-       
-#ifdef USE_QT_CORE
-       
-       app.exec();
-       
-#else
-       
-       g_main_loop_run(mainLoop);
-       
-#endif
+               
+       mainloop = loader.mainloop();
+
+       /* Register signal handler */
+       signal(SIGINT, interrupt);
+       signal(SIGTERM, interrupt);
+
+       mainloop->exec();
        
        if(logfile.is_open())
                logfile.close();
index b51fc96..c310456 100644 (file)
@@ -18,10 +18,13 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 
 
 #include "pluginloader.h"
+#include "glibmainloop.h"
+
 #include <iostream>
 #include <stdexcept>
 #include <json-glib/json-glib.h>
 
+
 using namespace std;
 
 /********************************************
@@ -33,7 +36,7 @@ using namespace std;
  * 
 **********************************************/
 
-PluginLoader::PluginLoader(string configFile, AbstractRoutingEngine* re): f_create(NULL), routingEngine(re)
+PluginLoader::PluginLoader(string configFile, AbstractRoutingEngine* re, int argc, char** argv): f_create(NULL), routingEngine(re), mMainLoop(nullptr)
 {
        DebugOut()<<"Loading config file: "<<configFile<<endl;
        
@@ -56,13 +59,34 @@ PluginLoader::PluginLoader(string configFile, AbstractRoutingEngine* re): f_crea
                throw std::runtime_error("Unable to create JSON reader");
        
        DebugOut()<<"Config members: "<<json_reader_count_members(reader)<<endl;
-               
-       json_reader_read_member(reader,"sources");
-       
-       const GError * srcReadError = json_reader_get_error(reader);
+
+       if(json_reader_read_member(reader,"mainloop"))
+       {
+               /// there is a mainloop entry.  Load the plugin:
+
+               string mainloopstr = json_reader_get_string_value(reader);
+
+               mMainLoop = loadMainLoop(mainloopstr,argc, argv);
+
+               if(!mMainLoop)
+               {
+                       DebugOut(0)<<"Failed to load main loop plugin."<<endl;
+               }
+       }
+       else if(!mMainLoop)
+       {
+               /// there is no mainloop entry, use default glib
+               DebugOut()<<"No mainloop specified in config.  Using glib by default."<<endl;
+               mMainLoop = new GlibMainLoop(argc,argv);
+       }
        
-       if(srcReadError != nullptr)
+       json_reader_end_member(reader);
+
+       if(!json_reader_read_member(reader,"sources"))
        {
+
+               const GError * srcReadError = json_reader_get_error(reader);
+
                DebugOut()<<"Error getting sources member: "<<srcReadError->message<<endl;
                throw std::runtime_error("Error getting sources member");
        }
@@ -164,6 +188,11 @@ SinkList PluginLoader::sinks()
        return mSinks;
 }
 
+IMainLoop *PluginLoader::mainloop()
+{
+       return mMainLoop;
+}
+
 SourceList PluginLoader::sources()
 {
        return mSources;
index d0489c8..09384e6 100644 (file)
@@ -28,24 +28,26 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 #include "abstractsink.h"
 #include "abstractroutingengine.h"
 #include "debugout.h"
-
+#include "imainloop.h"
 
 
 using namespace std;
 
 typedef void* create_t(AbstractRoutingEngine*, map<string, string> );
-
+typedef void* create_mainloop_t(int argc, char** argv);
 
 class PluginLoader
 {
 
 public:
-       PluginLoader(string configFile, AbstractRoutingEngine* routingEngine);
+       PluginLoader(string configFile, AbstractRoutingEngine* routingEngine, int argc, char** argv);
        ~PluginLoader();
 
        SourceList sources();
        SinkList sinks();
 
+       IMainLoop* mainloop();
+
        std::string errorString();
         
        
@@ -86,6 +88,39 @@ private: ///methods:
                
                return nullptr;
        }
+
+       IMainLoop* loadMainLoop(string pluginName, int argc, char** argv)
+               {
+                       DebugOut()<<"Loading plugin: "<<pluginName<<endl;
+
+                       if(lt_dlinit())
+                       {
+                               mErrorString = lt_dlerror();
+                               cerr<<"error initializing libtool: "<<__FILE__<<" - "<<__FUNCTION__<<":"<<__LINE__<<" "<<mErrorString<<endl;
+                               return nullptr;
+                       }
+
+                       lt_dlerror();
+
+                       lt_dlhandle handle = lt_dlopenext(pluginName.c_str());
+
+                       if(!handle)
+                       {
+                               mErrorString = lt_dlerror();
+                               cerr<<"error opening plugin: "<<pluginName<<" in "<<__FILE__<<" - "<<__FUNCTION__<<":"<<__LINE__<<" "<<mErrorString<<endl;
+                               return nullptr;
+                       }
+
+                       m_create = (create_mainloop_t *)lt_dlsym(handle, "create");
+
+                       if(m_create)
+                       {
+                               void* obj = m_create(argc, argv);
+                               return static_cast<IMainLoop*>( obj );
+                       }
+
+                       return nullptr;
+               }
        
 private:
        
@@ -98,6 +133,10 @@ private:
        SinkList mSinks;
        
        create_t * f_create;
+       create_mainloop_t * m_create;
+
+
+       IMainLoop* mMainLoop;
 };
 
 #endif // PLUGINLOADER_H
diff --git a/ambd/qtmainloop.cpp b/ambd/qtmainloop.cpp
new file mode 100644 (file)
index 0000000..be884f4
--- /dev/null
@@ -0,0 +1,22 @@
+#include "qtmainloop.h"
+
+extern "C" IMainLoop * create(int argc, char** argv)
+{
+       return new QtMainLoop(argc, argv);
+}
+
+QtMainLoop::QtMainLoop(int argc, char** argv)
+       :IMainLoop(argc,argv)
+{
+       app = new QCoreApplication(argc,argv);
+}
+
+QtMainLoop::~QtMainLoop()
+{
+       app->exit(0);
+}
+
+int QtMainLoop::exec()
+{
+       app->exec();
+}
diff --git a/ambd/qtmainloop.h b/ambd/qtmainloop.h
new file mode 100644 (file)
index 0000000..a3d7aff
--- /dev/null
@@ -0,0 +1,19 @@
+#ifndef _QTMAINLOOP_H_
+#define _QTMAINLOOP_H_
+
+#include <QCoreApplication>
+#include "imainloop.h"
+
+class QtMainLoop: public IMainLoop
+{
+public:
+
+       QtMainLoop(int argc, char **argv);
+       ~QtMainLoop();
+
+       int exec();
+private:
+       QCoreApplication* app;
+};
+
+#endif
diff --git a/examples/qtmainloopconfig b/examples/qtmainloopconfig
new file mode 100644 (file)
index 0000000..0318255
--- /dev/null
@@ -0,0 +1,18 @@
+{
+       "mainloop" : "/usr/lib/automotive-message-broker/qtmainloopplugin.so",
+       "sources" : [ 
+               {
+                       "name" : "ExampleSouce",
+                       "path" : "/usr/lib/automotive-message-broker/examplesourceplugin.so"
+               }
+       ],
+       "sinks": [
+               {
+                       "name" : "Example sink",
+                       "path" : "/usr/lib/automotive-message-broker/examplesinkplugin.so",
+                       "interface" : "lo",
+                       "port" : "23000"
+               } 
+       ]
+}
+
index 00717c2..d8b2035 100644 (file)
@@ -216,7 +216,7 @@ VehicleProperty::VehicleProperty()
        REGISTERPROPERTY(TransmissionFluidLevel,0);
        REGISTERPROPERTY(BrakeFluidLevel,0);
        REGISTERPROPERTY(WasherFluidLevel,0);
-       REGISTERPROPERTY(SecurityAlertStatus,0);
+       REGISTERPROPERTY(SecurityAlertStatus,Security::Idle);
        REGISTERPROPERTY(ParkingBrakeStatus,false);
        REGISTERPROPERTY(ParkingLightStatus,false);
        REGISTERPROPERTY(HazardLightStatus,false);
index ce755b7..f6f1e6f 100644 (file)
@@ -27,4 +27,4 @@ add_subdirectory(demosink)
 add_subdirectory(websocketsourceplugin)
 add_subdirectory(tpms)
 add_subdirectory(database)
-add_subdirectory(opencvlux)
+#add_subdirectory(opencvlux)
index 77684dd..9a06036 100644 (file)
@@ -18,7 +18,7 @@ public:
                 *  @type boolean
                 *  @access readonly
                 **/
-               wantProperty<bool>(VehicleProperty::SecurityAlertStatus,"SecurityAlert", "b", AbstractProperty::Read);
+               wantProperty<Security::Status>(VehicleProperty::SecurityAlertStatus,"SecurityAlert", "i", AbstractProperty::Read);
 
                supportedChanged(re->supported());
        }