From 5815060246f84e8efdf3143b4e8c7d00778168cf Mon Sep 17 00:00:00 2001 From: =?utf8?q?Enar=20V=C3=A4ikene?= Date: Thu, 21 Apr 2011 16:05:15 +0300 Subject: [PATCH] Added more sources to the common library. Removed other modules from the build system so that the common lib can be compiled. --- src/CMakeLists.txt | 4 +- src/libs/CMakeLists.txt | 2 +- src/libs/Common/CMakeLists.txt | 49 ++++++++ src/libs/Common/app.cpp | 6 +- src/libs/Common/app.h | 4 +- src/libs/Common/env.cpp | 200 +++++++++++++++++++++++++++++++++ src/libs/Common/env.h | 86 ++++++++++++++ src/libs/Common/event.cpp | 24 ++++ src/libs/Common/event.h | 4 +- src/libs/Common/eventqueue.cpp | 155 +++++++++++++++++++++++++ src/libs/Common/eventqueue.h | 86 ++++++++++++++ src/libs/Common/iapp.h | 3 +- src/libs/Common/ienv.h | 4 +- src/libs/Common/ieventqueue.h | 10 +- src/libs/Common/ilogger.h | 2 +- src/libs/Common/registry.cpp | 6 +- 16 files changed, 629 insertions(+), 16 deletions(-) create mode 100644 src/libs/Common/CMakeLists.txt create mode 100644 src/libs/Common/env.cpp create mode 100644 src/libs/Common/env.h create mode 100644 src/libs/Common/event.cpp create mode 100644 src/libs/Common/eventqueue.cpp create mode 100644 src/libs/Common/eventqueue.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 79123e7..dc43d15 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,3 +1,3 @@ add_subdirectory(libs) -add_subdirectory(main) -add_subdirectory(plugins) +#add_subdirectory(main) +#add_subdirectory(plugins) diff --git a/src/libs/CMakeLists.txt b/src/libs/CMakeLists.txt index 918e3ce..d20916f 100644 --- a/src/libs/CMakeLists.txt +++ b/src/libs/CMakeLists.txt @@ -1,2 +1,2 @@ -add_subdirectory(Plugins) +#add_subdirectory(Plugins) add_subdirectory(Common) diff --git a/src/libs/Common/CMakeLists.txt b/src/libs/Common/CMakeLists.txt new file mode 100644 index 0000000..1d16647 --- /dev/null +++ b/src/libs/Common/CMakeLists.txt @@ -0,0 +1,49 @@ +# Name of the target +set(TARGET CommonLib) + +# Qt modules +include(${QT_USE_FILE}) + +# Needed for exporting/importing symbols +add_definitions(-DCOMMON_LIBRARY) + +# Include files +include_directories(${eVaf_INCLUDE}) + +# Required eVaf libraries +set(eVaf_LIBRARIES) + +# Source files +set(SRCS + app.cpp + env.cpp + event.cpp + eventqueue.cpp + registry.cpp +) + +# Header files for the meta-object compiler +set(MOC_HDRS + iapp.h + ienv.h + ieventqueue.h + ilogger.h + iregistry.h + app.h + env.h + eventqueue.h + registry.h +) + +# Version info resource file for Windows builds +if(WIN32) + set(SRCS ${SRCS} version.rc) +endif(WIN32) + +qt4_wrap_cpp(MOC_SRCS ${MOC_HDRS}) + +add_library(${TARGET} SHARED ${SRCS} ${MOC_SRCS}) + +target_link_libraries(${TARGET} ${QT_LIBRARIES} ${eVaf_LIBRARIES}) + +install(TARGETS ${TARGET} DESTINATION bin) diff --git a/src/libs/Common/app.cpp b/src/libs/Common/app.cpp index 6f28942..3956548 100644 --- a/src/libs/Common/app.cpp +++ b/src/libs/Common/app.cpp @@ -32,7 +32,7 @@ using namespace eVaf::Common; iApp * iApp::instance() { - Internal::App singleton; + static Internal::App singleton; return &singleton; } @@ -95,6 +95,8 @@ bool App::init() else if (QRegExp("-[-]?lang(uage)?").exactMatch(arg.at(0)) && arg.size() > 1) mLanguage = arg.at(1); } + + return true; } QString const App::xmlFileName() const @@ -112,7 +114,7 @@ QString const App::xmlFileName() const name = mName + "_" + mLanguage.left(2) + ".xml"; fi.setFile(iEnv::instance()->etcDir() + name); if (fi.isReadable()) - mName = name; + mXmlFile = name; else // Fall-back to the generic name mXmlFile = mName + ".xml"; diff --git a/src/libs/Common/app.h b/src/libs/Common/app.h index c954641..1cf1fde 100644 --- a/src/libs/Common/app.h +++ b/src/libs/Common/app.h @@ -59,7 +59,7 @@ public: virtual void restart(); - virtual void quit(); + virtual void quit(bool err); virtual bool isReady() const { return mReady; } @@ -76,7 +76,7 @@ private: QString mLanguage; /// Name of the application's XML file - QString mXmlFile; + mutable QString mXmlFile; }; diff --git a/src/libs/Common/env.cpp b/src/libs/Common/env.cpp new file mode 100644 index 0000000..55b133e --- /dev/null +++ b/src/libs/Common/env.cpp @@ -0,0 +1,200 @@ +/** + * @file Common/env.cpp + * @brief iEnv interface implementation + * @author Enar Vaikene + * + * Copyright (c) 2011 Enar Vaikene + * + * This file is part of the eVaf C++ cross-platform application development framework. + * + * This file can be used under the terms of the GNU General Public License + * version 3.0 as published by the Free Software Foundation and appearing in + * the file LICENSE included in the packaging of this file. Please review the + * the following information to ensure the GNU General Public License version + * 3.0 requirements will be met: http://www.gnu.org/copyleft/gpl.html. + * + * Alternatively, this file may be used in accordance with the Commercial License + * Agreement provided with the Software. + */ + +#include "env.h" +#include "iregistry.h" +#include "globals.h" +#include "version.h" +#include "iapp.h" + +#include +#include + + +//------------------------------------------------------------------- + +using namespace eVaf::Common; + +iEnv * iEnv::instance() +{ + static Internal::Env singleton; + return &singleton; +} + + +//------------------------------------------------------------------- + +using namespace eVaf::Common::Internal; + +Env::Env() + : iEnv() +{ + setObjectName(QString("%1-iEnv").arg(VER_MODULE_NAME_STR)); + + // Set initial bin and root directories + mRootDir = mBinDir = qApp->applicationDirPath(); + int t = mBinDir.lastIndexOf(QChar('/'), -1); + if (t >= 0) + mRootDir = mBinDir.left(t); + + if (!mBinDir.endsWith('/')) + mBinDir.append('/'); + if (!mRootDir.endsWith('/')) + mRootDir.append('/'); +} + +Env::~Env() +{ +} + +bool Env::init() +{ + // Register out interface + iRegistry::instance()->registerInterface("iEnv", this); + + // Clear directories + mDataRootDir.clear(); + mQtPluginsDir.clear(); + mEtcDir.clear(); + mLogDir.clear(); + mDocDir.clear(); + + // Process the environment + QStringList env = QProcess::systemEnvironment(); + int sz = env.size(); + for (int i = 0; i < sz; ++i) { + // Get the name/value pair + QString name = env.at(i).section('=', 0, 0).trimmed(); + QString value = env.at(i).section('=', 1).trimmed(); + + if (name == "EVAF_ROOT_DIR") { + mRootDir = value; + if (!mRootDir.endsWith('/')) + mRootDir.append('/'); + } + else if (name == "EVAF_DATA_ROOT_DIR") { + mDataRootDir = value; + if (!mDataRootDir.endsWith('/')) + mDataRootDir.append('/'); + } + else if (name == "EVAF_ETC_DIR") { + mEtcDir = value; + if (!mEtcDir.endsWith('/')) + mEtcDir.append('/'); + } + else if (name == "EVAF_LOG_DIR") { + mLogDir = value; + if (!mLogDir.endsWith('/')) + mLogDir.append('/'); + } + else if (name == "EVAF_DOC_DIR") { + mDocDir = value; + if (!mDocDir.endsWith('/')) + mDocDir.append('/'); + } + else if (name == "EVAF_QT_PLUGINS_DIR") { + mQtPluginsDir = value; + if (!mQtPluginsDir.endsWith('/')) + mQtPluginsDir.append('/'); + } + } + + // Then process comman-line arguments + env = QCoreApplication::arguments(); + sz = env.size(); + for (int i = 0; i < sz; ++i) { + // Get the name and optional value + QStringList arg = env.at(i).simplified().split(QChar('=')); + + if (QRegExp("-[-]?root(dir)?").exactMatch(arg.at(0)) && arg.size() > 1) { + mRootDir = arg.at(1); + if (!mRootDir.endsWith('/')) + mRootDir.append('/'); + } + else if (QRegExp("-[-]?dataroot(dir)?").exactMatch(arg.at(0)) && arg.size() > 1) { + mDataRootDir = arg.at(1); + if (!mDataRootDir.endsWith('/')) + mDataRootDir.append('/'); + } + else if (QRegExp("-[-]?etc(dir)?").exactMatch(arg.at(0)) && arg.size() > 1) { + mEtcDir = arg.at(1); + if (!mEtcDir.endsWith('/')) + mEtcDir.append('/'); + } + else if (QRegExp("-[-]?log(dir)?").exactMatch(arg.at(0)) && arg.size() > 1) { + mLogDir = arg.at(1); + if (!mLogDir.endsWith('/')) + mLogDir.append('/'); + } + else if (QRegExp("-[-]?doc(dir)?").exactMatch(arg.at(0)) && arg.size() > 1) { + mDocDir = arg.at(1); + if (!mDocDir.endsWith('/')) + mDocDir.append('/'); + } + else if (QRegExp("-[-]?qtplugins(dir)?").exactMatch(arg.at(0)) && arg.size() > 1) { + mQtPluginsDir = arg.at(1); + if (!mQtPluginsDir.endsWith('/')) + mQtPluginsDir.append('/'); + } + } + + return true; +} + +QString const Env::dataRootDir() const +{ + if (mDataRootDir.isEmpty()) { + QString dataLoc = QDesktopServices::storageLocation(QDesktopServices::DataLocation); + if (!dataLoc.endsWith('/')) + dataLoc.append('/'); + mDataRootDir = dataLoc.append(iApp::instance()->name()); + if (!mDataRootDir.endsWith('/')) + mDataRootDir.append('/'); + } + + return mDataRootDir; +} + +QString const Env::etcDir() const +{ + if (mEtcDir.isEmpty()) + mEtcDir = dataRootDir() + "etc/"; + return mEtcDir; +} + +QString const Env::logDir() const +{ + if (mLogDir.isEmpty()) + mLogDir = dataRootDir() + "log/"; + return mLogDir; +} + +QString const Env::docDir() const +{ + if (mDocDir.isEmpty()) + mDocDir = rootDir() + "doc/"; + return mDocDir; +} + +QString const Env::qtPluginsDir() const +{ + if (mQtPluginsDir.isEmpty()) + mQtPluginsDir = binDir(); + return mQtPluginsDir; +} diff --git a/src/libs/Common/env.h b/src/libs/Common/env.h new file mode 100644 index 0000000..592db2c --- /dev/null +++ b/src/libs/Common/env.h @@ -0,0 +1,86 @@ +/** + * @file Common/env.h + * @brief iEnv interface implementation + * @author Enar Vaikene + * + * Copyright (c) 2011 Enar Vaikene + * + * This file is part of the eVaf C++ cross-platform application development framework. + * + * This file can be used under the terms of the GNU General Public License + * version 3.0 as published by the Free Software Foundation and appearing in + * the file LICENSE included in the packaging of this file. Please review the + * the following information to ensure the GNU General Public License version + * 3.0 requirements will be met: http://www.gnu.org/copyleft/gpl.html. + * + * Alternatively, this file may be used in accordance with the Commercial License + * Agreement provided with the Software. + */ + +#ifndef __COMMON_ENV_H +#define __COMMON_ENV_H + +#include "ienv.h" + +#include +#include + +namespace eVaf { +namespace Common { +namespace Internal { + +/** + * iEnv interface implementation + */ +class Env : public iEnv +{ + Q_OBJECT + +public: + + Env(); + + virtual ~Env(); + + /** + * Initializes the iEnv interface implementation + * @return True if ok; false if the initialization fails + */ + bool init(); + + /* + iEnv interface + */ + + virtual QString const rootDir() const { return mRootDir; } + + virtual QString const dataRootDir() const; + + virtual QString const binDir() const { return mBinDir; } + + virtual QString const etcDir() const; + + virtual QString const logDir() const; + + virtual QString const docDir() const; + + virtual QString const qtPluginsDir() const; + + +private: // Members + + QString mRootDir; + mutable QString mDataRootDir; + QString mBinDir; + mutable QString mQtPluginsDir; + mutable QString mEtcDir; + mutable QString mLogDir; + mutable QString mDocDir; + +}; + +} // namespace eVaf::Common::Internal +} // namespace eVaf::Common +} // namespace eVaf + +#endif // env.h diff --git a/src/libs/Common/event.cpp b/src/libs/Common/event.cpp new file mode 100644 index 0000000..be9f34b --- /dev/null +++ b/src/libs/Common/event.cpp @@ -0,0 +1,24 @@ +/** + * @file Common/event.cpp + * @brief Event class implementation + * @author Enar Vaikene + * + * Copyright (c) 2011 Enar Vaikene + * + * This file is part of the eVaf C++ cross-platform application development framework. + * + * This file can be used under the terms of the GNU General Public License + * version 3.0 as published by the Free Software Foundation and appearing in + * the file LICENSE included in the packaging of this file. Please review the + * the following information to ensure the GNU General Public License version + * 3.0 requirements will be met: http://www.gnu.org/copyleft/gpl.html. + * + * Alternatively, this file may be used in accordance with the Commercial License + * Agreement provided with the Software. + */ + +#include "event.h" + +using namespace eVaf::Common; + +QEvent::Type const Event::eVafEvent = QEvent::Type(QEvent::registerEventType()); diff --git a/src/libs/Common/event.h b/src/libs/Common/event.h index 91f33c9..960b53e 100644 --- a/src/libs/Common/event.h +++ b/src/libs/Common/event.h @@ -31,10 +31,10 @@ namespace eVaf { namespace Common { /** - * Base class for all the eVaf events + * Event class for all the eVaf events * @code@include @endcode * - * The Event class is an event container for reference counted data objects. + * The Event class is an event container for all the eVaf events. */ class COMMON_EXPORT Event : public QEvent { diff --git a/src/libs/Common/eventqueue.cpp b/src/libs/Common/eventqueue.cpp new file mode 100644 index 0000000..bbf30ed --- /dev/null +++ b/src/libs/Common/eventqueue.cpp @@ -0,0 +1,155 @@ +/** + * @file Common/eventqueue.cpp + * @brief Event queue interface implementation + * @author Enar Vaikene + * + * Copyright (c) 2011 Enar Vaikene + * + * This file is part of the eVaf C++ cross-platform application development framework. + * + * This file can be used under the terms of the GNU General Public License + * version 3.0 as published by the Free Software Foundation and appearing in + * the file LICENSE included in the packaging of this file. Please review the + * the following information to ensure the GNU General Public License version + * 3.0 requirements will be met: http://www.gnu.org/copyleft/gpl.html. + * + * Alternatively, this file may be used in accordance with the Commercial License + * Agreement provided with the Software. + */ + +#include "eventqueue.h" +#include "event.h" +#include "globals.h" +#include "iregistry.h" +#include "version.h" + +#include + + +//------------------------------------------------------------------- + +using namespace eVaf::Common; + +iEventQueue * iEventQueue::instance() +{ + static Internal::EventQueue singleton; + return &singleton; +} + + +//------------------------------------------------------------------- + +using namespace eVaf::Common::Internal; + +EventQueue::EventQueue() + : iEventQueue() + , mNextEventId(1) +{ +} + +EventQueue::~EventQueue() +{ +} + +bool EventQueue::event(QEvent * e) +{ + // Is it an eVaf event? + if (e->type() == Event::eVafEvent) { + + Event * event = static_cast(e); + + uint id = event->id(); + + // Verify that this event is registered + QHash::const_iterator eventsIt = mEvents.constFind(id); + if (eventsIt == mEvents.constEnd()) { + return true; // We don't know it, but it is an eVaf event and we should handle it + } + + // Send the event to all the subscribers + QHash > >::const_iterator subscribersIt = mSubscribers.constFind(id); + if (subscribersIt != mSubscribers.constEnd()) { + QList > subscribers = *subscribersIt; + int sz = subscribers.size(); + for (int i = 0; i < sz; ++i) { + + // Get the subscriber object and make sure that it is still alive + QPointer obj = subscribers.at(i); + if (obj.isNull()) { + continue; + } + + // Notify the subscriber + bool rval = QCoreApplication::sendEvent(obj, e); + + if (rval) { + // The event was consumed and should be sent to any other subscribers + break; + } + } + } + + return true; + } + else + return iEventQueue::event(e); +} + +uint EventQueue::registerEvent(QString const & name) +{ + uint id = queryEvent(name); + + if (id == 0) { + mEvents.insert(mNextEventId, name); + id = mNextEventId++; + } + + return id; +} + +uint EventQueue::queryEvent(QString const & name) const +{ + return mEvents.key(name, 0); +} + +void EventQueue::unregisterEvent(uint id) +{ + mEvents.remove(id); + mSubscribers.remove(id); +} + +uint EventQueue::subscribeEvent(uint id, QObject * obj) +{ + if (id == 0) + return 0; + + // Only registered events please + if (mEvents.constFind(id) == mEvents.constEnd()) { + return 0; + } + + // Check for duplicates + if (mSubscribers[id].indexOf(obj) != -1) + return id; + + mSubscribers[id].append(obj); + + return id; +} + +void EventQueue::unsubscribeEvent(uint id, QObject * obj) +{ + if (id == 0) + return; + + // Is the event registered? + if (mEvents.constFind(id) == mEvents.constEnd()) + return; + + mSubscribers[id].removeAll(obj); +} + +void EventQueue::broadcastEvent(Event * event) +{ + QCoreApplication::postEvent(this, event); +} diff --git a/src/libs/Common/eventqueue.h b/src/libs/Common/eventqueue.h new file mode 100644 index 0000000..92bcb06 --- /dev/null +++ b/src/libs/Common/eventqueue.h @@ -0,0 +1,86 @@ +/** + * @file Common/eventqueue.h + * @brief Event queue interface implementation + * @author Enar Vaikene + * + * Copyright (c) 2011 Enar Vaikene + * + * This file is part of the eVaf C++ cross-platform application development framework. + * + * This file can be used under the terms of the GNU General Public License + * version 3.0 as published by the Free Software Foundation and appearing in + * the file LICENSE included in the packaging of this file. Please review the + * the following information to ensure the GNU General Public License version + * 3.0 requirements will be met: http://www.gnu.org/copyleft/gpl.html. + * + * Alternatively, this file may be used in accordance with the Commercial License + * Agreement provided with the Software. + */ + +#ifndef __COMMON_EVENTQUEUE_H +#define __COMMON_EVENTQUEUE_H + +#include "ieventqueue.h" + +#include +#include +#include +#include +#include + + +namespace eVaf { +namespace Common { +namespace Internal { + +/** + * iEventQueue interface implementation + */ +class EventQueue : public iEventQueue +{ + Q_OBJECT + +public: + + EventQueue(); + + virtual ~EventQueue(); + + /// Qt event handler + virtual bool event(QEvent * e); + + /* + iEventQueue interface + */ + + virtual uint registerEvent(QString const & name); + + virtual uint queryEvent(QString const & name) const; + + virtual void unregisterEvent(uint id); + + virtual uint subscribeEvent(uint id, QObject * obj); + + virtual void unsubscribeEvent(uint id, QObject * obj); + + virtual void broadcastEvent(Event * event); + + +private: // Members + + /// ID of the next event + uint mNextEventId; + + /// List of registered events + QHash mEvents; + + /// List of subscribers + QHash > > mSubscribers; + +}; + +} // namespace evaf::Common::Internal +} // namespace eVaf::Common +} // namespace eVaf + +#endif // eventqueue.h diff --git a/src/libs/Common/iapp.h b/src/libs/Common/iapp.h index 8028589..5329e1b 100644 --- a/src/libs/Common/iapp.h +++ b/src/libs/Common/iapp.h @@ -130,10 +130,11 @@ public: /** * Requests the eVaf application to quit. + * @param err If true, then indicates that the application exits due to a fatal error * * This function requests the eVaf application to quit. */ - virtual void quit() = 0; + virtual void quit(bool err) = 0; /** * Returns true if the eVaf application is ready. diff --git a/src/libs/Common/ienv.h b/src/libs/Common/ienv.h index 0eba5ea..2effd2c 100644 --- a/src/libs/Common/ienv.h +++ b/src/libs/Common/ienv.h @@ -90,7 +90,7 @@ public: * on Linux is ${HOME}/.${EVAF_APP_NAME}. * * This directory can be changed with the EVAF_DATA_ROOT_DIR environment variable or with the - * -data[root[dir]]=<directory> command line argument. + * -dataroot[dir]=<directory> command line argument. */ virtual QString const dataRootDir() const = 0; @@ -146,7 +146,7 @@ public: * Changing this directory does not affect the way how Qt itself loads its plugins. * * This directory can be changed with the EVAF_QT_PLUGINS_DIR environment variable or with the - * -qt[plugins[dir]]=<directory> command line argument. + * -qtplugins[dir]=<directory> command line argument. */ virtual QString const qtPluginsDir() const = 0; diff --git a/src/libs/Common/ieventqueue.h b/src/libs/Common/ieventqueue.h index ce12e42..bf60a67 100644 --- a/src/libs/Common/ieventqueue.h +++ b/src/libs/Common/ieventqueue.h @@ -1,6 +1,6 @@ /** * @file Common/ieventqueue.h - * @brief Event queue interfaces + * @brief Event queue interface * @author Enar Vaikene * * Copyright (c) 2011 Enar Vaikene @@ -28,6 +28,8 @@ namespace eVaf { namespace Common { +class Event; + /** * The eVaf event queue interface * @code#include @endcode @@ -48,6 +50,12 @@ public: /// Empty virtual destructor virtual ~iEventQueue() {} + /** + * Returns the instance of the iEventQueue interface + * @return The iEventQueue interface + */ + static iEventQueue * instance(); + /** * Registers an event * @param name Name of the event diff --git a/src/libs/Common/ilogger.h b/src/libs/Common/ilogger.h index ecc4858..4a75e3e 100644 --- a/src/libs/Common/ilogger.h +++ b/src/libs/Common/ilogger.h @@ -79,7 +79,7 @@ public: * are expected to be linked against the Common library, then this is the preferred method of obtaining * the iLogger interface. The other method is by using the iRegistry interface. */ - static iLogger::instance(); + static iLogger * instance(); /** * Returns the current default source name. diff --git a/src/libs/Common/registry.cpp b/src/libs/Common/registry.cpp index c0f9cae..d93e469 100644 --- a/src/libs/Common/registry.cpp +++ b/src/libs/Common/registry.cpp @@ -41,7 +41,7 @@ using namespace eVaf::Common::Internal; Registry::Registry() : iRegistry() { - setObjectName(QString("%1-iRegistry").arg(VER_MODULENAME_STR)); + setObjectName(QString("%1-iRegistry").arg(VER_MODULE_NAME_STR)); // Register our own interface registerInterface("iRegistry", this); @@ -55,9 +55,11 @@ Registry::~Registry() bool Registry::registerInterface(QString const & name, QObject * obj) { mInterfaces.insert(name, QPointer(obj)); + + return true; } -QObject * Registry::queryInterface(QString const & name) +QObject * Registry::queryInterface(QString const & name) const { QHash >::const_iterator it = mInterfaces.constFind(name); return it != mInterfaces.constEnd() ? *it : 0; -- 2.45.2