Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Comparing changes

Choose two branches to see what's changed or to start a new pull request. If you need to, you can also compare across forks.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also compare across forks.
  • 16 commits
  • 78 files changed
  • 0 commit comments
  • 1 contributor
Showing with 1,440 additions and 481 deletions.
  1. +0 −2  .astylerc
  2. +1 −1  .githooks/post-commit/generate-ctags
  3. +2 −0  CMakeLists.txt
  4. +2 −0  TODO
  5. +44 −21 cmake/Modules/WintermutePluginMacros.cmake
  6. +4 −2 cmake/Modules/WintermuteTestingMacros.cmake
  7. +17 −7 cmake/Modules/WintermuteVariables.cmake
  8. +24 −11 doc/Procedures.md
  9. +23 −0 doc/StartingUp.markdown
  10. +4 −0 lib/daemon/README.md
  11. +3 −1 lib/daemon/globals.hpp
  12. +3 −1 lib/daemon/globals.hpp.in
  13. +26 −2 lib/daemon/module.cpp
  14. +4 −1 lib/daemon/module.hpp
  15. +2 −2 lib/daemon/plugin.cpp
  16. +1 −0  lib/daemon/plugin.hpp
  17. +7 −3 lib/dbus/CMakeLists.txt
  18. +8 −1 lib/dbus/README.md
  19. +79 −0 lib/dbus/adaptor.cpp
  20. +62 −0 lib/dbus/adaptor.hpp
  21. +23 −8 lib/dbus/dispatcher.cpp
  22. +1 −1  lib/dbus/globals.hpp.in
  23. +14 −4 lib/dbus/module.cpp
  24. +7 −1 lib/dbus/module.hpp
  25. +5 −2 lib/dbus/plugin.cpp
  26. +21 −0 lib/dbus/receiver.cpp
  27. +24 −0 lib/dbus/receiver.hpp
  28. +0 −2  lib/heartbeat/CMakeLists.txt
  29. +15 −0 lib/heartbeat/module.cpp
  30. +1 −0  lib/heartbeat/module.hpp
  31. +7 −1 lib/zeromq/CMakeLists.txt
  32. +3 −2 lib/zeromq/dispatcher.cpp
  33. +9 −9 lib/zeromq/module.cpp
  34. +1 −3 lib/zeromq/module.hpp
  35. +1 −1  lib/zeromq/plugin.cpp
  36. +3 −3 lib/zeromq/receiver.cpp
  37. +5 −2 src/CMakeLists.txt
  38. +42 −17 src/Wintermute/Events/Filters/call.cpp
  39. +4 −0 src/Wintermute/Events/Filters/call.hpp
  40. +1 −1  src/Wintermute/Events/call.cpp
  41. +1 −1  src/Wintermute/Events/call.hpp
  42. +1 −1  src/Wintermute/Factory
  43. +19 −0 src/Wintermute/PluginProcess
  44. +33 −16 src/Wintermute/Procedure/call.cpp
  45. +15 −27 src/Wintermute/Procedure/call.hpp
  46. +3 −3 src/Wintermute/Procedure/dummy_dispatcher.cpp
  47. +2 −1  src/Wintermute/Procedure/dummy_receiver.cpp
  48. +26 −6 src/Wintermute/Procedure/lambda_call.cpp
  49. +15 −4 src/Wintermute/Procedure/lambda_call.hpp
  50. +39 −6 src/Wintermute/Procedure/method_call.cpp
  51. +13 −4 src/Wintermute/Procedure/method_call.hpp
  52. +36 −12 src/Wintermute/Procedure/module.cpp
  53. +27 −1 src/Wintermute/Procedure/module.hpp
  54. +16 −6 src/Wintermute/Procedure/process_module.cpp
  55. +5 −2 src/Wintermute/Procedure/process_module.hpp
  56. +10 −15 lib/heartbeat/calls/greet.hpp → src/Wintermute/Procedure/reply_call.hpp
  57. +31 −19 src/Wintermute/application.cpp
  58. +15 −14 src/Wintermute/application.hpp
  59. +5 −33 src/Wintermute/arguments.cpp
  60. +51 −23 src/Wintermute/factory.cpp
  61. +12 −3 src/Wintermute/factory.hpp
  62. +13 −7 src/Wintermute/logging.hpp
  63. +7 −3 src/Wintermute/plugin.cpp
  64. +28 −16 src/Wintermute/plugin.hpp
  65. +61 −0 src/Wintermute/plugin_process.cpp
  66. +43 −0 src/Wintermute/plugin_process.hpp
  67. +6 −4 src/Wintermute/private/Procedure/call.hpp
  68. +13 −2 src/Wintermute/private/Procedure/dispatcher.hpp
  69. +11 −1 src/Wintermute/private/Procedure/method_call.hpp
  70. +10 −7 src/Wintermute/private/Procedure/module.hpp
  71. +23 −15 src/Wintermute/private/Procedure/receiver.hpp
  72. +71 −24 src/Wintermute/private/application.hpp
  73. +60 −0 src/Wintermute/private/arguments.hpp
  74. +97 −71 src/Wintermute/private/factory.hpp
  75. +35 −4 src/Wintermute/private/logging.hpp
  76. +13 −6 src/Wintermute/private/plugin.hpp
  77. +46 −0 src/Wintermute/private/plugin_process.hpp
  78. +25 −12 src/globals.hpp.in
View
2  .astylerc
@@ -6,8 +6,6 @@
indent=spaces=2
indent-switches
indent-cases
-pad-oper
-pad-paren
pad-header
convert-tabs
View
2  .githooks/post-commit/generate-ctags
@@ -40,5 +40,5 @@ case "${1}" in
echo "[ctags] Generating tags for repository..."
PWD=$TOPLEVELGITDIR ctags -R $TOPLEVELGITDIR/*
echo "[ctags] Tags generated; update tag clients."
- ;;
+ ;;
esac
View
2  CMakeLists.txt
@@ -23,6 +23,8 @@ cmake_policy(SET CMP0017 NEW)
## system's logic.
set(CMAKE_MODULE_PATH
${CMAKE_CURRENT_SOURCE_DIR}/cmake/Modules)
+set(CMAKE_INSTALL_DEFAULT_COMPONENT_NAME
+ Runtime)
set(WINTERMUTE_BUILD_PREFIX
${CMAKE_INSTALL_PREFIX})
set(WINTERMUTE_PLUGIN_DEFINITION_TEMPLATE
View
2  TODO
@@ -59,6 +59,8 @@ CURRENT TASKS:
@ Added [Sun 2013-09-29]
- Incorporate a documenting tool (issue #11).
@ Added [Sun 2013-09-29]
+ - Implement the use of a state machine.
+
COMPLETED TASKS:
# vim:ft=quicktask
View
65 cmake/Modules/WintermutePluginMacros.cmake
@@ -1,5 +1,5 @@
###############################################################################
-### Copyright (C) 2013 Jacky Alciné <me@jalcine.me>
+### Copyright (C) 2013 - 2014 Jacky Alciné <me@jalcine.me>
###
### This file is part of Wintermute, the extensible AI platform.
###
@@ -30,7 +30,8 @@ include(WintermuteVariables)
## plugin.
if (NOT DEFINED WINTERMUTE_PLUGIN_DEFINITION_TEMPLATE)
- set(WINTERMUTE_PLUGIN_DEFINITION_TEMPLATE "${WINTERMUTE_CMAKE_TEMPLATES_DIR}/PluginDefinition.spec.in")
+ set(WINTERMUTE_PLUGIN_DEFINITION_TEMPLATE
+ "${WINTERMUTE_CMAKE_TEMPLATES_DIR}/PluginDefinition.spec.in")
endif()
##
@@ -44,7 +45,7 @@ endif()
##
function(wintermute_plugin_declare)
set(_oneArgs TARGET)
- set(_multiArgs SOURCES)
+ set(_multiArgs SOURCES HEADERS)
cmake_parse_arguments(wdp "" "${_oneArgs}" "${_multiArgs}" ${ARGN})
# Define the plugin's CMake prefix.
@@ -53,13 +54,21 @@ function(wintermute_plugin_declare)
string(TOUPPER ${wdp_TARGET} ${_local}_EXPORT_SYMBOL)
# Define the plugin's CMake properties.
- set(${_local}_SOURCES ${wdp_SOURCES} CACHE STRING "Sources.")
- set(${_local}_TARGET "wintermute-${wdp_TARGET}" CACHE STRING "Target.")
- set(${_local}_LIBRARIES ${WINTERMUTE_LIBRARIES} CACHE STRING "Libraries.")
+ set(${_local}_SOURCES ${wdp_SOURCES}
+ CACHE STRING "Sources.")
+ set(${_local}_HEADERS ${wdp_HEADERS}
+ CACHE STRING "Headers.")
+ set(${_local}_TARGET "wintermute-${wdp_TARGET}"
+ CACHE STRING "Target.")
+ set(${_local}_LIBRARIES ${WINTERMUTE_LIBRARIES}
+ CACHE STRING "Libraries.")
set(${_local}_INCLUDE_DIRS ${WINTERMUTE_INCLUDE_DIRS}
- ${WINTERMUTE_INCLUDE_DIR} CACHE STRING INTERNAL FORCE)
- set(${_local}_HEADERS_PATH "${WINTERMUTE_INCLUDE_DIR}/plugins/${_minLocal}" CACHE STRING "Headers install.")
- set(${_local}_DEFINITION_FILE "${CMAKE_BINARY_DIR}/plugin-${wdp_TARGET}.spec" CACHE STRING "Def.")
+ ${WINTERMUTE_INCLUDE_DIR}
+ CACHE STRING INTERNAL FORCE)
+ set(${_local}_HEADERS_PATH "${WINTERMUTE_PLUGIN_INCLUDE_DIR}/${_minLocal}"
+ CACHE STRING "Headers install.")
+ set(${_local}_DEFINITION_FILE "${CMAKE_BINARY_DIR}/plugin-${wdp_TARGET}.spec"
+ CACHE STRING "Definitions file.")
endfunction(wintermute_plugin_declare)
@@ -172,7 +181,8 @@ function(wintermute_plugin_configure)
string(TOUPPER "WINTERMUTE_PLUGIN_${wpc_TARGET}" _local)
foreach(_validProperty ${_validProperties})
- set("${_local}${_validProperty}" "${wpc_${_validProperty}}" CACHE STRING "Configuration property.")
+ set("${_local}${_validProperty}" "${wpc_${_validProperty}}"
+ CACHE STRING "Configuration property.")
endforeach(_validProperty ${_validProperties})
endfunction(wintermute_plugin_configure)
@@ -199,11 +209,15 @@ function(wintermute_plugin_set_version)
string(TOUPPER "WINTERMUTE_PLUGIN_${wpsv_TARGET}" _local)
foreach(_pluginVersionVariable ${_pluginVersions})
- set("${_local}${_pluginVersionVariable}" "${wpsv_${_pluginVersionVariable}}" CACHE STRING "Versioning.")
+ set("${_local}_${_pluginVersionVariable}"
+ "${wpsv_${_pluginVersionVariable}}"
+ CACHE STRING "Versioning.")
endforeach(_pluginVersionVariable ${_pluginVersions})
foreach(_systemVersionVariable ${_systemVersions})
- set("${_local}${_systemVersionVariable}" "${wpsv_${_systemVersionVariable}}" CACHE STRING "System versioning.")
+ set("${_local}${_systemVersionVariable}"
+ "${wpsv_${_systemVersionVariable}}"
+ CACHE STRING "System versioning.")
endforeach(_systemVersionVariable ${_systemVersions})
endfunction(wintermute_plugin_set_version)
@@ -217,21 +231,30 @@ function(wintermute_plugin_install)
cmake_parse_arguments(wpi "" "TARGET" "" ${ARGN})
string(TOUPPER "WINTERMUTE_PLUGIN_${wpi_TARGET}" _local)
- # DONE: Define the plug-in's definition file.
set(${_local}_DEFINITION_FILE "${CMAKE_BINARY_DIR}/${${_local}_TARGET}.spec")
configure_file(${WINTERMUTE_PLUGIN_DEFINITION_TEMPLATE} ${${_local}_DEFINITION_FILE})
- # DONE: Install the library itself.
install(TARGETS ${${_local}_TARGET}
- LIBRARY DESTINATION ${WINTERMUTE_PLUGIN_LIBRARY_DIR}
- )
+ EXPORT ${${_local}_TARGET}
+ COMPONENT Runtime
+ LIBRARY DESTINATION ${WINTERMUTE_PLUGIN_LIBRARY_DIR}
+ )
- # TODO: Install exported information.
- # TODO: Install build-time headers.
+ install(EXPORT ${${_local}_TARGET}
+ COMPONENT Development
+ CONFIGURATIONS Debug
+ DESTINATION ${WINTERMUTE_CMAKE_MODULES_DIR}
+ )
+
+ install(FILES ${${_local}_HEADERS}
+ COMPONENT Development
+ CONFIGURATIONS Debug
+ DESTINATION ${${_local}_HEADERS_PATH}
+ )
# TODO: Install documentation.
- # DONE: Generate the definition file.
- # DONE: Install the definition file.
install(FILES ${${_local}_DEFINITION_FILE}
- DESTINATION ${WINTERMUTE_PLUGIN_DEFINITION_DIR})
+ COMPONENT Runtime
+ CONFIGURATIONS Release
+ DESTINATION ${WINTERMUTE_PLUGIN_DEFINITION_DIR})
endfunction(wintermute_plugin_install)
View
6 cmake/Modules/WintermuteTestingMacros.cmake
@@ -26,11 +26,13 @@ file(GLOB_RECURSE WINTERMUTE_TEST_CORE_SOURCES
macro(wintermute_add_unit_test unittestname unittestsrc)
# Define sources and moc them up.
- SET(unittest_${unittestname}_SRCS ${unittestsrc} ${WINTERMUTE_TEST_CORE_SOURCES})
+ SET(unittest_${unittestname}_SRCS ${unittestsrc}
+ ${WINTERMUTE_TEST_CORE_SOURCES})
qt4_automoc(${unittest_${unittestname}_SRCS})
# Set up the test as if it was Wintermute.
- add_executable(unittest_${unittestname} ${unittest_${unittestname}_SRCS})
+ add_executable(unittest_${unittestname} EXCLUDE_FROM_ALL
+ ${unittest_${unittestname}_SRCS})
wintermute_add_properties(unittest_${unittestname})
target_link_libraries(unittest_${unittestname} ${WINTERMUTE_TEST_LIBRARIES})
View
24 cmake/Modules/WintermuteVariables.cmake
@@ -43,30 +43,40 @@ set(WINTERMUTE_CMAKE_MODULES_DIR
"${WINTERMUTE_BUILD_PREFIX}/${CMAKE_INSTALL_DATAROOTDIR}/cmake-${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}/Modules")
# Define the defintions to use.
-set(WINTERMUTE_COMPILE_DEFINITIONS WINTERMUTE)
-set(WINTERMUTE_COMPILE_DEFINITIONS_DEBUG WINTERMUTE_DEBUG DEBUG)
-set(WINTERMUTE_COMPILE_DEFINITIONS_RELEASE WINTERMUTE_RELEASE RELEASE NDEBUG)
+set(WINTERMUTE_COMPILE_DEFINITIONS
+ WINTERMUTE)
+set(WINTERMUTE_COMPILE_DEFINITIONS_DEBUG
+ WINTERMUTE_DEBUG DEBUG)
+set(WINTERMUTE_COMPILE_DEFINITIONS_RELEASE
+ WINTERMUTE_RELEASE RELEASE NDEBUG)
# Define the flags for linking and compiling.
-set(WINTERMUTE_COMPILE_FLAGS "-std=c++0x -Wall")
-set(WINTERMUTE_COMPILE_FLAGS_RELEASE "-Ofast -frtti")
-set(WINTERMUTE_COMPILE_FLAGS_DEBUG "-g -O0 -Wextra -Wall -Wunused-parameter -Wunused-function -Wunused -Wno-system-headers -Wno-deprecated -Woverloaded-virtual -Wwrite-strings -Wabi -Wempty-body -Winit-self -Woverflow -fprofile-arcs -ftest-coverage")
+set(WINTERMUTE_COMPILE_FLAGS
+ "-std=c++0x -Wall")
+set(WINTERMUTE_COMPILE_FLAGS_RELEASE
+ "-Ofast -frtti")
+set(WINTERMUTE_COMPILE_FLAGS_DEBUG
+ "-g -O0 -Wextra -Wall -Wunused-parameter -Wunused-function -Wunused -Wno-system-headers -Wno-deprecated -Woverloaded-virtual -Wwrite-strings -Wabi -Wempty-body -Winit-self -Woverflow -fprofile-arcs -ftest-coverage")
set(WINTERMUTE_LINK_FLAGS )
-set(WINTERMUTE_LINK_FLAGS_DEBUG "-fprofile-arcs -ftest-coverage -lgcov")
+set(WINTERMUTE_LINK_FLAGS_DEBUG
+ "-fprofile-arcs -ftest-coverage -lgcov")
set(WINTERMUTE_LINK_FLAGS_RELEASE )
set(WINTERMUTE_LIBRARIES
Log4Qt
${QJSON_LIBRARIES}
${QCOMMANDLINE_LIBRARIES}
+ ${QT_QTCORE_LIBRARY}
)
set(WINTERMUTE_INCLUDE_DIRS
${LOG4QT_INCLUDE_DIRS}
${QJSON_INCLUDE_DIRS}
${QCOMMANDLINE_INCLUDE_DIR}
+ ${QT_QTCORE_INCLUDE_DIR}
)
set(WINTERMUTE_PLUGIN_LIBRARY_DIR "${WINTERMUTE_LIBRARY_DIR}")
+set(WINTERMUTE_PLUGIN_INCLUDE_DIR "${WINTERMUTE_CORE_INCLUDE_DIR}/Plugins")
set(WINTERMUTE_PLUGIN_DEFINITION_DIR "${WINTERMUTE_DATA_DIR}/plugindefs")
## Some CMake things we'd need.
View
35 doc/Procedures.md
@@ -1,21 +1,34 @@
# Procedure Calling
-Wintermute abstracts its IPC system with the `Wintermute::Procedure` classes.
-Under the hood, the primary means of RPC is implemented by [ZeroMQ][] and
-provided by the `wintermute-tcpip` library that works to implement the network
-powered solutions for RPC provided by ZeroMQ (primarily `tcp`). The system is
-split up into calls, modules, dispatchers and receivers.
+Wintermute abstracts its IPC system with the classes found under the
+`Wintermute::Procedure` namespace. Under the hood, Wintermute isn't quite sure
+*how* the call from one process to another gets there but Wintermute does the
+work necessary to inform invokers of the arrival of a call as well as
+returning a reply once handled.
## Calls
Call objects are the representation of action and data that's shuffled back
and forth over a communication protocol. They serve two purposes, to list the
-valid calls available on a `Module` and to hold the proper information
-required for invocation on a remote instance of Wintermute.
+valid calls available on a **Module** and to hold the proper information
+required for invocation on a remote instance of Wintermute. The implementation
+for calls are a bit tricky. They can be serialized into a format usable to
+send over the wire, yet these functors are required to handle invocation to
+begin with. Think of them as a data type with an invokable nature.
## Modules
-Modules are objects that hold a collection of methods under a specific
-name space, i.e: 'me.jalcine.wintermute.process' or
-'me.jalcine.wintermute.daemon'. Multiple modules can be 'mounted' or hooked in
-a way that they are discoverable by W
+Modules are objects that hold a collection of calls under a specific namespace.
+Multiple modules can be instantiated in the same process and in multiple
+processes at the same time; allowing for common logic to be shared in said
+processes. An example of this would be the `ProcessModule`; which would allow
+for remote control of the local process. Another would be the modules provided
+by the transports used for dispatching and receiving calls like `ZeroMQ::Module`.
+
+## Messaging
+
+Wintermute sends all messages using the Dispatcher system and receives using
+the Receiver system. The process is straightforward. When a call is set to be
+dispatched, it's serialized into a format appropriate for messaging and then
+sent over all of the available dispatchers to be caught by the proper process.
+Receivers then listen for these calls and then
View
23 doc/StartingUp.markdown
@@ -0,0 +1,23 @@
+# Starting Up Wintermute
+
+The idea here for starting and running Wintermute is meant to be universal
+across the (potentially) different language implementations of the software to
+allow for a common core concept of the application.
+
+## Cold Start
+
+When Wintermute is invoked from the command line, the very thing to occur is
+the initialization of its logging system. It'd send all of its output to disk
+and to the current terminal output window. After that, it checks the
+designated mode for this instance of Wintermute to run as[^1]. Right now, it's
+configured to pick between a **daemon** mode or a **plugin** mode. The daemon
+mode is a quasi-alias toward the invocation of the `wintermute-daemon` plugin.
+
+### Starting As the Daemon
+
+The daemon instance of Wintermute has to start the plug-ins designated by the
+configured list set at build-time (defined by WINTERMUTE_DAEMON_STARTUP_LIST).
+
+[^1]: The information about modes can be discovered in
+ `src/Wintermute/private/application.hpp` in the
+ `Wintermute::ApplicationPrivate` in the `loadCurrentMode()` function.
View
4 lib/daemon/README.md
@@ -1,2 +1,6 @@
# Daemon
+The daemon of Wintermute has two purposes: to start and to watch. It has to
+**start** the plug-ins designated for the start-up phase of Wintermute and to
+ensure that they start running and be restarted if they happened to stop
+abnormally.
View
4 lib/daemon/globals.hpp
@@ -1,6 +1,6 @@
/**
* vim: ft=cpp tw=78
- * Copyright (C) 2013 Jacky Alciné <me@jalcine.me>
+ * Copyright (C) 2013, 2014 Jacky Alciné <me@jalcine.me>
*
* Wintermute is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -19,4 +19,6 @@
#ifndef WINTERMUTE_PLUGIN_DAEMON_GLOBALS_HPP
#define WINTERMUTE_PLUGIN_DAEMON_GLOBALS_HPP
+#define WINTERMUTE_DAEMON_STARTUP_LIST "wintermute-heartbeat"
+
#endif /* */
View
4 lib/daemon/globals.hpp.in
@@ -1,6 +1,6 @@
/**
* vim: ft=cpp tw=78
- * Copyright (C) 2013 Jacky Alciné <me@jalcine.me>
+ * Copyright (C) 2013, 2014 Jacky Alciné <me@jalcine.me>
*
* Wintermute is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -19,4 +19,6 @@
#ifndef WINTERMUTE_PLUGIN_DAEMON_GLOBALS_HPP
#define WINTERMUTE_PLUGIN_DAEMON_GLOBALS_HPP
+#define WINTERMUTE_DAEMON_STARTUP_LIST "wintermute-heartbeat"
+
#endif /* */
View
28 lib/daemon/module.cpp
@@ -1,6 +1,6 @@
/**
* vim: ft=cpp tw=78
- * Copyright (C) 2013 Jacky Alciné <me@jalcine.me>
+ * Copyright (C) 2013, 2014 Jacky Alciné <me@jalcine.me>
*
* Wintermute is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -16,9 +16,17 @@
* along with Wintermute. If not, see <http://www.gnu.org/licenses/>.
**/
+#include <QtCore/QSettings>
+#include <QtCore/QDateTime>
+#include <QtCore/QVariant>
+#include <QtCore/QStringList>
#include <Wintermute/Application>
+#include <Wintermute/Logging>
+#include <Wintermute/Factory>
+#include <Wintermute/PluginProcess>
#include "module.hpp"
#include "plugin.hpp"
+#include "globals.hpp"
#include "module.moc"
using Wintermute::Daemon::Module;
@@ -33,7 +41,23 @@ Module::Module ( Daemon::Plugin* plugin ) : Wintermute::Procedure::Module ( plug
void
Module::start()
{
- // TODO: Spawn out a few plug-ins needed for kicking up Wintermute.
+ QStringList values = QString(WINTERMUTE_DAEMON_STARTUP_LIST).split(';');
+ winfo(this, QString("Plugins to start up: %1.")
+ .arg(WINTERMUTE_DAEMON_STARTUP_LIST));
+ startUpPlugins(values);
+}
+
+void
+Module::startUpPlugins(const QStringList& plugins)
+{
+ Q_FOREACH(const QString & plugin, plugins)
+ {
+ winfo(wntrFactory,
+ QString("Invoking %1 for daemon startup...").arg(plugin));
+ const PluginProcess* process = wntrFactory->spawnPlugin(plugin);
+ winfo(wntrFactory,
+ QString("Started daemon plugin '%1'.").arg(plugin));
+ }
}
Module::~Module()
View
5 lib/daemon/module.hpp
@@ -33,8 +33,11 @@ class Module : public Wintermute::Procedure::Module
explicit Module ( Daemon::Plugin* plugin );
Q_SLOT virtual void start();
virtual ~Module();
+
+private:
+ void startUpPlugins(const QStringList& plugins);
};
}
}
-#endif /* */
+#endif /* WINTERMUTE_DAEMON_PLUGIN_MODULE_HPP */
View
4 lib/daemon/plugin.cpp
@@ -45,7 +45,7 @@ Plugin::stop()
void
Plugin::start()
{
- // TODO Ask for the loading of a messaging plug-in.
+ // TODO
}
Version
@@ -72,4 +72,4 @@ Plugin::type() const
return Module;
}
-Q_EXPORT_PLUGIN2 ( wintermute-daemon, Wintermute::Daemon::Plugin );
+Q_EXPORT_PLUGIN2 ( wintermute - daemon, Wintermute::Daemon::Plugin );
View
1  lib/daemon/plugin.hpp
@@ -31,6 +31,7 @@ class Plugin : public Wintermute::Plugin
Q_OBJECT;
Q_DISABLE_COPY ( Plugin );
Wintermute::Daemon::Module* module;
+ friend class Wintermute::Daemon::Module;
public:
explicit Plugin();
View
10 lib/dbus/CMakeLists.txt
@@ -1,5 +1,5 @@
##############################################################################
-### Copyright (C) 2013 Jacky Alciné <me@jalcine.me>
+### Copyright (C) 2013, 2014 Jacky Alciné <me@jalcine.me>
###
### This file is part of Wintermute, the extensible AI platform.
###
@@ -19,15 +19,19 @@
project ( WintermuteDBus )
set ( dbus_SRCS
plugin.cpp
+ module.cpp
+ adaptor.cpp
dispatcher.cpp
receiver.cpp
- module.cpp )
+)
set ( dbus_HDRS
plugin.hpp
dispatcher.hpp
+ adaptor.hpp
receiver.hpp
- module.hpp )
+ module.hpp
+)
configure_file ( globals.hpp.in ${CMAKE_SOURCE_DIR}/lib/dbus/globals.hpp
@ONLY )
View
9 lib/dbus/README.md
@@ -1 +1,8 @@
-# D-Bus Support in Wintermute.
+# D-Bus Support in Wintermute
+
+This plugin for Wintermute allows each instance to expose itself over
+[D-Bus][dbus]; a binary messaging protocol between applications used on Linux.
+This can be used in place or in conjunction to other transports like
+[ZeroMQ](../zeromq/README.md) to allow for local applications a means of
+communication with Wintermute. This is a substitute until a helper library for
+external application communication into Wintermute's network can be devised.
View
79 lib/dbus/adaptor.cpp
@@ -0,0 +1,79 @@
+/**
+ * vim: ft=cpp tw=78
+ * Copyright (C) 2014 Jacky Alciné <me@jalcine.me>
+ *
+ * Wintermute is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Wintermute is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Wintermute. If not, see <http://www.gnu.org/licenses/>.
+ **/
+
+#include <QtDBus/QDBusConnection>
+#include <QtCore/QCoreApplication>
+#include <Wintermute/Logging>
+#include "module.hpp"
+#include "receiver.hpp"
+#include "adaptor.hpp"
+#include "adaptor.moc"
+
+using Wintermute::DBus::Adaptor;
+using Wintermute::DBus::Receiver;
+using Wintermute::Procedure::Call;
+
+Adaptor::Adaptor( Module* module ) :
+ QDBusAbstractAdaptor( module )
+{
+ winfo (this, "Adaptor created.");
+}
+
+void
+Adaptor::registerOnDBus()
+{
+ QDBusConnection bus = QDBusConnection::sessionBus();
+ const bool serviceRegistered = bus.registerService ( QString (
+ "in.wintermute.p%1" ).arg( QCoreApplication::applicationPid() ) );
+
+ if ( !serviceRegistered )
+ {
+ werr (this, "Failed to register service with D-Bus.");
+ return;
+ }
+
+ const bool objectRegistered = bus.registerObject( "/Process", parent(),
+ QDBusConnection::ExportChildObjects | QDBusConnection::ExportAllSlots
+ | QDBusConnection::ExportAllInvokables | QDBusConnection::ExportAdaptors
+ | QDBusConnection::ExportChildObjects
+ );
+
+ if ( objectRegistered )
+ {
+ winfo ( this, QString( "Registered this process into D-Bus service %1." )
+ .arg ( bus.baseService() ) );
+ }
+}
+
+void
+Adaptor::handleIncomingCall ( const QString& arguments, const
+ QDBusMessage& message )
+{
+ const Call* incomingCall = Call::fromString ( arguments );
+ ((Module*) parent())->m_receiver->receiveMessage(incomingCall);
+}
+
+bool
+Adaptor::hasModule ( const QString& name )
+{
+ return false;
+}
+
+Adaptor::~Adaptor()
+{
+}
View
62 lib/dbus/adaptor.hpp
@@ -0,0 +1,62 @@
+/**
+ * vim: ft=cpp tw=78
+ * Copyright (C) 2014 Jacky Alciné <me@jalcine.me>
+ *
+ * Wintermute is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Wintermute is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Wintermute. If not, see <http://www.gnu.org/licenses/>.
+ **/
+
+#ifndef WINTERMUTE_DBUS_ADADPTOR_HPP
+#define WINTERMUTE_DBUS_ADADPTOR_HPP
+
+#include <QtDBus/QDBusAbstractAdaptor>
+#include <QtDBus/QDBusMessage>
+#include <Wintermute/Globals>
+#include <Wintermute/Procedure/Call>
+#include "globals.hpp"
+
+namespace Wintermute
+{
+namespace DBus
+{
+class Module;
+class Adaptor : public QDBusAbstractAdaptor
+{
+ Q_OBJECT;
+ Q_CLASSINFO ( "D-Bus Interface", "in.wintermute.dbus" );
+ Q_CLASSINFO("D-Bus Introspection", ""
+" <interface name=\"in.wintermute.dbus\">\n"
+" <method name=\"handleIncomingCall\">\n"
+" <arg direction=\"in\" type=\"s\" name=\"arguments\"/>\n"
+" <annotation value=\"true\" name=\"org.freedesktop.DBus.Method.NoReply\"/>\n"
+" </method>\n"
+" <method name=\"hasModule\">\n"
+" <arg direction=\"out\" type=\"b\"/>\n"
+" <arg direction=\"in\" type=\"s\" name=\"name\"/>\n"
+" </method>\n"
+" </interface>\n"
+ "")
+ public:
+ explicit Adaptor( Module* module );
+ void registerOnDBus();
+ virtual ~Adaptor();
+
+ public slots:
+ Q_NOREPLY void handleIncomingCall ( const QString& arguments,
+ const QDBusMessage& message );
+ bool hasModule ( const QString& name );
+};
+}
+}
+
+#endif
View
31 lib/dbus/dispatcher.cpp
@@ -19,6 +19,7 @@
#include <Wintermute/Logging>
#include <Wintermute/Procedure/Call>
#include <QtDBus/QDBusInterface>
+#include <QtDBus/QDBusConnectionInterface>
#include <QtDBus/QDBusReply>
#include "dispatcher.hpp"
#include "module.hpp"
@@ -38,14 +39,28 @@ Dispatcher::~Dispatcher()
}
void
-Dispatcher::sendMessage ( const Call* message )
+Dispatcher::sendMessage ( const Call* call )
{
- const QByteArray data = message->toString().toUtf8();
QDBusConnection sessionBus = QDBusConnection::sessionBus();
- QDBusMessage methodCall = QDBusMessage::createMethodCall ( WINTERMUTE_DOMAIN,
- "/Receiver", message->recipient(), "handleCall" );
- methodCall << data;
- QDBusPendingReply<QString> methodCallState = sessionBus.asyncCall ( methodCall );
- methodCallState.waitForFinished();
- winfo ( this, "Invoked call over D-Bus; though the pending call isn't being caught." );
+ QDBusConnectionInterface* interface = sessionBus.interface();
+ QStringList remoteServices = interface->registeredServiceNames();
+ QStringList friendlyServices = remoteServices.filter ( WINTERMUTE_DOMAIN );
+ friendlyServices.removeAll ( sessionBus.name() );
+ if ( friendlyServices.empty() )
+ {
+ winfo (this, "No services found that are friendly to Wintermute " +
+ QString("of the known %1 services.").arg(remoteServices.length()));
+ return;
+ }
+ else
+ {
+ Q_FOREACH(const QString remoteService, friendlyServices)
+ {
+ winfo (this, QString("Sending call to %1").arg ( remoteService ));
+ QDBusMessage methodCall = QDBusMessage::createMethodCall ( remoteService,
+ "/Process", WINTERMUTE_DOMAIN ".dbus" , "handleIncomingCall" );
+ methodCall << call->toString();
+ QDBusPendingReply<QString> methodCallState = sessionBus.asyncCall ( methodCall );
+ }
+ }
}
View
2  lib/dbus/globals.hpp.in
@@ -1,6 +1,6 @@
/**
* vim: ft=cpp tw=78
- * Copyright (C) 2013 Jacky Alciné <me@jalcine.me>
+ * Copyright (C) 2013, 2014 Jacky Alciné <me@jalcine.me>
*
* Wintermute is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
View
18 lib/dbus/module.cpp
@@ -1,6 +1,6 @@
/**
* vim: ft=cpp tw=78
- * Copyright (C) 2013 Jacky Alciné <me@jalcine.me>
+ * Copyright (C) 2013, 2014 Jacky Alciné <me@jalcine.me>
*
* Wintermute is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -20,27 +20,37 @@
#include <Wintermute/Application>
#include <Wintermute/Globals>
#include <Wintermute/Logging>
+#include <Wintermute/Procedure/Call>
#include "module.hpp"
#include "plugin.hpp"
+#include "adaptor.hpp"
#include "dispatcher.hpp"
+#include "receiver.hpp"
#include "module.moc"
using Wintermute::DBus::Module;
using Wintermute::DBus::Plugin;
using Wintermute::DBus::Dispatcher;
+using Wintermute::Procedure::Call;
-Module::Module ( DBus::Plugin* plugin ) : Wintermute::Procedure::Module ( plugin )
+Module::Module ( DBus::Plugin* plugin ) :
+ Wintermute::Procedure::Module ( plugin ),
+ m_dispatcher ( 0 ), m_receiver ( 0 )
{
setDomain ( WINTERMUTE_DOMAIN );
setPackage ( "dbus" );
- Dispatcher* dispatcher = new Dispatcher;
- dispatcher->setParent ( this );
+ m_adaptor = new Adaptor ( this );
+ m_dispatcher = new Dispatcher;
+ m_receiver = new Receiver;
+ m_dispatcher->setParent ( this );
+ m_receiver->setParent ( this );
}
void
Module::start()
{
// TODO: Create the interface to listen for replies.
+ m_adaptor->registerOnDBus();
}
Module::~Module()
View
8 lib/dbus/module.hpp
@@ -26,10 +26,16 @@ namespace Wintermute
namespace DBus
{
class Plugin;
+class Dispatcher;
+class Receiver;
+class Adaptor;
class Module : public Wintermute::Procedure::Module
{
Q_OBJECT;
- friend class Dispatcher;
+ Dispatcher* m_dispatcher;
+ Receiver* m_receiver;
+ Adaptor* m_adaptor;
+ friend class Adaptor;
public:
explicit Module ( DBus::Plugin* plugin );
Q_SLOT virtual void start();
View
7 lib/dbus/plugin.cpp
@@ -44,18 +44,21 @@ void
Plugin::start()
{
module = new DBus::Module ( this );
+ module->start();
}
Version
Plugin::version() const
{
- return Version::fromString ( configuration()->value ( "Version/Plugin" ).toString() );
+ return Version::fromString ( configuration()->value (
+ "Version/Plugin" ).toString() );
}
Version
Plugin::systemVersion() const
{
- return Version::fromString ( configuration()->value ( "Version/System" ).toString() );
+ return Version::fromString ( configuration()->value (
+ "Version/System" ).toString() );
}
Plugin::State
View
21 lib/dbus/receiver.cpp
@@ -17,4 +17,25 @@
**/
#include <Wintermute/Logging>
+#include "adaptor.hpp"
+#include "receiver.hpp"
+#include "receiver.moc"
+using Wintermute::DBus::Receiver;
+using Wintermute::DBus::Adaptor;
+using Wintermute::Procedure::Call;
+
+Receiver::Receiver() :
+ Wintermute::Procedure::Receiver()
+{
+}
+
+void
+Receiver::receiveMessage ( const Call* call )
+{
+ Wintermute::Procedure::Receiver::receiveMessage(call);
+}
+
+Receiver::~Receiver()
+{
+}
View
24 lib/dbus/receiver.hpp
@@ -15,3 +15,27 @@
* You should have received a copy of the GNU General Public License
* along with Wintermute. If not, see <http://www.gnu.org/licenses/>.
**/
+
+#ifndef WINTERMUTE_DBUS_RECEIVER_HPP
+#define WINTERMUTE_DBUS_RECEIVER_HPP
+
+#include <Wintermute/Procedure/Receiver>
+#include <Wintermute/Procedure/Call>
+
+namespace Wintermute
+{
+namespace DBus
+{
+class Adaptor;
+class Receiver : public Wintermute::Procedure::Receiver
+{
+ Q_OBJECT;
+ public:
+ explicit Receiver();
+ virtual ~Receiver();
+ Q_SLOT virtual void receiveMessage(const Procedure::Call* call);
+};
+}
+}
+
+#endif
View
2  lib/heartbeat/CMakeLists.txt
@@ -20,13 +20,11 @@ project ( WintermuteHeartbeat )
set ( heartbeat_SRCS
plugin.cpp
module.cpp
- calls/greet.cpp
)
set ( heartbeat_HDRS
plugin.hpp
module.hpp
- calls/greet.hpp
)
configure_file ( globals.hpp.in ${CMAKE_SOURCE_DIR}/lib/heartbeat/globals.hpp
View
15 lib/heartbeat/module.cpp
@@ -19,12 +19,15 @@
#include <Wintermute/Application>
#include <Wintermute/Globals>
#include <Wintermute/Logging>
+#include <Wintermute/Procedure/Call>
#include "plugin.hpp"
#include "module.hpp"
#include "module.moc"
using Wintermute::Heartbeat::Module;
using Wintermute::Heartbeat::Plugin;
+using Wintermute::Procedure::Call;
+using Wintermute::Procedure::CallPointer;
Module::Module ( Heartbeat::Plugin* plugin ) :
Wintermute::Procedure::Module ( plugin )
@@ -34,9 +37,21 @@ Module::Module ( Heartbeat::Plugin* plugin ) :
winfo ( this, "Heartbeat ready to pulse." );
}
+// TODO Figure out how to use a bound reference to a method of an object in
+// std::function.
void
Module::start()
{
+ winfo ( this, "Started heartbeat module." );
+ Call::Signature greet;
+ mountLambda ( greet, "greet" );
+ winfo ( this, "Mounted calls for heartbeat." );
+}
+
+QVariant
+Module::callGreet( QVariantList arguments )
+{
+ winfo ( this, "Hey, look; you're here!" );
}
Module::~Module()
View
1  lib/heartbeat/module.hpp
@@ -29,6 +29,7 @@ class Plugin;
class Module : public Wintermute::Procedure::Module
{
Q_OBJECT;
+ QVariant callGreet(QVariantList arguments);
public:
explicit Module ( Heartbeat::Plugin* plugin );
Q_SLOT virtual void start();
View
8 lib/zeromq/CMakeLists.txt
@@ -30,12 +30,18 @@ set ( zeromq_HDRS
module.hpp
dispatcher.hpp
receiver.hpp
+ globals.hpp
)
configure_file ( globals.hpp.in ${CMAKE_SOURCE_DIR}/lib/zeromq/globals.hpp
@ONLY )
-wintermute_plugin_declare ( TARGET zeromq SOURCES ${zeromq_SRCS} )
+wintermute_plugin_declare (
+ TARGET zeromq
+ HEADERS ${zeromq_HDRS}
+ SOURCES ${zeromq_SRCS}
+)
+
wintermute_plugin_set_version ( TARGET zeromq
PLUGIN_VERSION_MAJOR 0
PLUGIN_VERSION_MINOR 1
View
5 lib/zeromq/dispatcher.cpp
@@ -1,6 +1,6 @@
/**
* vim: ft=cpp tw=78
- * Copyright (C) 2011 - 2013 Jacky Alciné <me@jalcine.me>
+ * Copyright (C) 2013 Jacky Alciné <me@jalcine.me>
*
* Wintermute is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -34,8 +34,9 @@ Dispatcher::Dispatcher ( Module* a_module ) :
{
setParent ( a_module );
m_socket = dynamic_cast<QtZeroMQ::PollingSocket*> (
- a_module->m_context->createSocket ( QtZeroMQ::Socket::TypePublish, this ) );
+ a_module->m_context->createSocket ( QtZeroMQ::Socket::TypePublish, this ) );
m_socket->bindTo ( WINTERMUTE_SOCKET_IPC );
+ winfo ( this, "Hey, sending over ZeroMQ." );
}
Dispatcher::~Dispatcher()
View
18 lib/zeromq/module.cpp
@@ -34,18 +34,17 @@ using Wintermute::ZeroMQ::Plugin;
using Wintermute::ZeroMQ::Dispatcher;
using Wintermute::ZeroMQ::Receiver;
-Module::Module ( ZeroMQ::Plugin* plugin ) :
+Module::Module ( ZeroMQ::Plugin* plugin ) :
Wintermute::Procedure::Module ( plugin ),
- m_context ( new QtZeroMQ::PollingContext ( this ) ),
- m_dispatcher ( 0 ),
- m_receiver ( 0 )
+ m_context ( new QtZeroMQ::PollingContext ( this ) )
{
setDomain ( WINTERMUTE_DOMAIN );
setPackage ( "zeromq" );
- m_receiver = new Receiver ( this );
- m_dispatcher = new Dispatcher ( this );
+ Receiver receiver ( this );
+ Dispatcher dispatcher ( this );
connect ( m_context, SIGNAL ( polled() ), this, SLOT ( pollInvoked() ) );
- connect ( m_context, SIGNAL ( pollError() ), this, SLOT ( pollError() ) );
+ connect ( m_context, SIGNAL ( pollError(int, const QString&) ),
+ this, SLOT ( pollError(int, const QString&) ) );
}
void
@@ -55,9 +54,10 @@ Module::pollInvoked()
}
void
-Module::pollError()
+Module::pollError(int errorNumber, const QString& errorMessage)
{
- // TODO Handle errors with polling.
+ werr(this, QString("ZeroMQ error %1: %2").
+ arg(QString::number(errorNumber), errorMessage));
}
void
View
4 lib/zeromq/module.hpp
@@ -46,10 +46,8 @@ class Module : public Wintermute::Procedure::Module
private:
void bindIncomingSocket();
Q_SLOT void pollInvoked();
- Q_SLOT void pollError();
+ Q_SLOT void pollError(int errorNumber, const QString& errorMessage);
QtZeroMQ::PollingContext* m_context;
- Dispatcher* m_dispatcher;
- Receiver* m_receiver;
};
}
}
View
2  lib/zeromq/plugin.cpp
@@ -71,4 +71,4 @@ Plugin::type() const
return Addon;
}
-Q_EXPORT_PLUGIN2 ( wintermute-zeromq, Wintermute::ZeroMQ::Plugin );
+Q_EXPORT_PLUGIN2 ( wintermute - zeromq, Wintermute::ZeroMQ::Plugin );
View
6 lib/zeromq/receiver.cpp
@@ -1,6 +1,6 @@
/**
* vim: ft=cpp tw=78
- * Copyright (C) 2011 - 2013 Jacky Alciné <me@jalcine.me>
+ * Copyright (C) 2011, 2012, 2013, 2014 Jacky Alciné <me@jalcine.me>
*
* Wintermute is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -35,7 +35,7 @@ Receiver::Receiver ( Module* a_module ) :
setParent ( a_module );
m_socket = dynamic_cast<QtZeroMQ::PollingSocket*> (
a_module->m_context->createSocket ( QtZeroMQ::Socket::TypeSubscribe, this ) );
- m_socket->subscribeTo ( QString ( "" ) );
+ m_socket->subscribeTo ( QString ( WINTERMUTE_SOCKET_IPC ) );
m_socket->connectTo ( WINTERMUTE_SOCKET_IPC );
winfo ( this, "Hey, listening on ZeroMQ." );
}
@@ -53,5 +53,5 @@ Receiver::onMessageReceived ( const QList<QByteArray>& data )
}
winfo ( this, QString ( "Obtained incoming call of %1 bytes." ).arg ( chunks.size() ) );
Call* receivedCall = Call::fromString ( chunks );
- receivedCall->invoke();
+ receivedCall->operator()();
}
View
7 src/CMakeLists.txt
@@ -1,5 +1,5 @@
###############################################################################
-### Copyright (C) 2013 Jacky Alciné <me@jalcine.me>
+### Copyright (C) 2013, 2014 Jacky Alciné <me@jalcine.me>
###
### This file is part of Wintermute, the extensible AI platform.
###
@@ -41,8 +41,9 @@ set ( WINTERMUTE_SOURCES
Wintermute/Procedure/dummy_receiver.cpp
## Plugin binaries
- Wintermute/plugin.cpp
Wintermute/factory.cpp
+ Wintermute/plugin.cpp
+ Wintermute/plugin_process.cpp
## Core binaries
Wintermute/logging.cpp
@@ -112,11 +113,13 @@ configure_file(${CMAKE_SOURCE_DIR}/src/globals.hpp.in ${CMAKE_SOURCE_DIR}/src/Wi
# Install the binary.
install(TARGETS wintermute
+ COMPONENT Runtime
RUNTIME DESTINATION ${WINTERMUTE_BIN_DIR})
foreach(_HDR ${WINTERMUTE_HEADERS})
string(FIND ${_HDR} / _dir_pos REVERSE)
string(SUBSTRING "${_HDR}" 0 ${_dir_pos} _DIR)
install(FILES ${_HDR}
+ COMPONENT Development
DESTINATION ${WINTERMUTE_INCLUDE_DIR}/${_DIR})
endforeach()
View
59 src/Wintermute/Events/Filters/call.cpp
@@ -20,7 +20,7 @@
#include "Wintermute/logging.hpp"
#include "Wintermute/Events/call.hpp"
#include "Wintermute/Events/Filters/call.hpp"
-#include "Wintermute/Procedure/call.hpp"
+#include "Wintermute/Procedure/method_call.hpp"
#include "Wintermute/private/Procedure/dispatcher.hpp"
#include "Wintermute/Events/Filters/call.moc"
@@ -35,25 +35,50 @@ CallFilter::CallFilter() :
}
bool
+CallFilter::handleDispatch ( QObject* object, QEvent* event )
+{
+ winfo ( object, "Handling a local call for dispatching aboard." );
+
+ CallEvent* callEvent = static_cast<CallEvent*> ( event );
+ const Procedure::Call* call = callEvent->call();
+
+ winfo ( object, QString ( "Dispatching %1 to '%2'." )
+ .arg ( call->toString(), call->recipient() ) );
+
+ Procedure::DispatcherPrivate::dispatch ( call->toString() );
+
+ winfo ( object, "Call dispatched." );
+
+ return true;
+}
+
+bool
+CallFilter::handleReceive ( QObject* object, QEvent* event )
+{
+ winfo ( object, "Handling a remote call for local invocation." );
+
+ CallEvent* callEvent = static_cast<CallEvent*> ( event );
+ const Procedure::Call* call = callEvent->call();
+ const bool invocated = Procedure::Call::attemptInvocation ( call );
+
+ invocated ? winfo ( object, "Call invoked." ) :
+ wwarn ( object, "Call failed to invoke." );
+
+ return true;
+}
+
+bool
CallFilter::eventFilter ( QObject* object, QEvent* event )
{
- if ( event->type() == CallEvent::TypeDispatch ) {
- winfo ( this, "Handling a local call for dispatching aboard." );
- CallEvent* callEvent = static_cast<CallEvent*> ( event );
- const Procedure::Call* call = callEvent->call();
- winfo ( this, QString ( "Call heading to %1." ).arg ( call->recipient() ) );
- Procedure::DispatcherPrivate::dispatch ( call->toString() );
- winfo ( this, "Call dispatched." );
- return true;
- } else if ( event->type() == CallEvent::TypeReceive ) {
- winfo ( this, "Handling a remote call for local invocation." );
- CallEvent* callEvent = static_cast<CallEvent*> ( event );
- const Procedure::Call* call = callEvent->call();
- const bool invocated = Procedure::Call::attemptInvocation ( call );
- invocated ? winfo ( this, "Call invoked." ) : wwarn ( this, "Call failed to invoke." );
- return true;
+ if ( event->type() == CallEvent::TypeDispatch )
+ {
+ return handleDispatch( object, event );
}
- // TODO: Filter out receive events.
+ else if ( event->type() == CallEvent::TypeReceive )
+ {
+ return handleReceive( object, event );
+ }
+
return QObject::eventFilter ( object, event );
}
View
4 src/Wintermute/Events/Filters/call.hpp
@@ -36,6 +36,10 @@ class CallFilter : public QObject
explicit CallFilter();
virtual ~CallFilter();
virtual bool eventFilter ( QObject* object, QEvent* event );
+
+private:
+ bool handleDispatch ( QObject* object, QEvent* event );
+ bool handleReceive ( QObject* object, QEvent* event );
};
}
}
View
2  src/Wintermute/Events/call.cpp
@@ -25,7 +25,7 @@ using Wintermute::Procedure::Call;
const int CallEvent::TypeReceive = QEvent::registerEventType();
const int CallEvent::TypeDispatch = QEvent::registerEventType();
-CallEvent::CallEvent ( int type, const Call* call ) :
+CallEvent::CallEvent ( const int type, const Call* call ) :
QEvent ( ( QEvent::Type ) type ) , m_call ( call )
{
}
View
2  src/Wintermute/Events/call.hpp
@@ -37,7 +37,7 @@ class CallEvent : public QEvent
public:
static const int TypeReceive;
static const int TypeDispatch;
- explicit CallEvent ( int type, const Procedure::Call* call );
+ explicit CallEvent ( const int type, const Procedure::Call* call );
virtual ~CallEvent();
const Procedure::Call* call() const;
};
View
2  src/Wintermute/Factory
@@ -1,6 +1,6 @@
/**
* vim: ft=cpp tw=78
- * Copyright (C) 2011 - 2013 Jacky Alciné <me@jalcine.me>
+ * Copyright (C) 2011, 2012, 2013, 2014 Jacky Alciné <me@jalcine.me>
*
* Wintermute is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
View
19 src/Wintermute/PluginProcess
@@ -0,0 +1,19 @@
+/**
+ * vim: ft=cpp tw=78
+ * Copyright (C) 2014 Jacky Alciné <me@jalcine.me>
+ *
+ * Wintermute is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Wintermute is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Wintermute. If not, see <http://www.gnu.org/licenses/>.
+ **/
+
+#include <Wintermute/plugin_process.hpp>
View
49 src/Wintermute/Procedure/call.cpp
@@ -32,16 +32,16 @@ Call::Call ( QObject* parent ) :
{
}
-Call::Call ( CallPrivate* d ) :
- QObject ( Wintermute::Application::instance() ), d_ptr ( d )
+Call::Call ( CallPrivate* old_d ) :
+ QObject ( Wintermute::Application::instance() ), d_ptr ( old_d )
{
+ Q_D ( Call );
+ d->q_ptr = this;
}
QVariant
Call::invoke ( const QVariantList& data )
{
- Q_D ( Call );
- return d->function ( data );
}
void
@@ -94,32 +94,49 @@ Call::fromString ( const QString& data )
QJson::Parser parser;
bool ok;
QVariant callData = parser.parse ( data.toLocal8Bit(), &ok );
- if ( !ok )
- { return 0; }
+ if ( !ok ) { return 0; }
QVariantMap callMap = callData.toMap();
- Call* aCall = new Call ( wntrApp );
- aCall->d_ptr->type = ( Call::Type ) callMap["type"].toInt();
- aCall->d_ptr->recipient = callMap["recipient"].toString();
- aCall->d_ptr->data = callMap["data"].toMap();
- return aCall;
+ CallPrivate* d_ptr = new CallPrivate(nullptr);
+ d_ptr->type = ( Call::Type ) callMap["type"].toInt();
+ d_ptr->recipient = callMap["recipient"].toString();
+ d_ptr->data = callMap["data"].toMap();
+ return new Call(d_ptr);
}
QVariant
Call::operator() ( const QVariantList& data )
{
- return this->invoke ( data );
+ return invoke ( data );
}
bool
Call::attemptInvocation ( const Call* call )
{
Procedure::Module* module = wntrApp->findModule ( call->recipient() );
- if ( !module ) {
- werr ( staticMetaObject.className(), QString ( "Can't find module '%1' in this process." ).arg ( call->recipient() ) );
+ if ( !module )
+ {
+ werr ( staticMetaObject.className(),
+ QString ( "Can't find module '%1' in this process." )
+ .arg ( call->recipient() ) );
return false;
}
- QVariant result = module->invoke ( call->d_ptr->data["method"].toString(), call->d_ptr->data["arguments"].toList() );
- winfo ( staticMetaObject.className(), result.toString() );
+
+ winfo ( staticMetaObject.className(),
+ QString ( "Found module %1 for invocation.")
+ .arg ( module->domain() + "." + module->package() ) );
+
+ const QString methodName = call->d_ptr->data[ "method" ].toString();
+ const QVariantList arguments = call->d_ptr->data[ "arguments" ].toList();
+
+ winfo ( staticMetaObject.className(),
+ QString( "Invoking %1 on %2..." )
+ .arg ( methodName, module->domain() + "." + module->package() ) );
+
+ QVariant result = module->invoke ( methodName, arguments );
+
+ winfo ( staticMetaObject.className(),
+ QString ( "Invocation result of %1: '%2'")
+ .arg ( methodName, result.toString() ) );
return true;
}
View
42 src/Wintermute/Procedure/call.hpp
@@ -16,10 +16,9 @@
* along with Wintermute. If not, see <http://www.gnu.org/licenses/>.
**/
-#ifndef WINTERMUTE_CORE_PROCEDURE_CALL_HPP
-#define WINTERMUTE_CORE_PROCEDURE_CALL_HPP
+#ifndef WINTERMUTE_PROCEDURE_CALL_HPP
+#define WINTERMUTE_PROCEDURE_CALL_HPP
-#include <functional>
#include <QtCore/QObject>
#include <QtCore/QVariant>
#include <QtCore/QSharedPointer>
@@ -40,20 +39,15 @@ class Call : public QObject
Call ( CallPrivate* d );
Q_ENUMS ( Type );
-public:
/**
- * @typedef Signature
- *
- * Provides the short-hand signature for Call methods.
+ * @fn invoke
+ * @param data A list of QVariant variables.
*/
- typedef std::function<QVariant ( QVariantList ) > Signature;
+ QVariant invoke ( const QVariantList& data = QVariantList() );
- /**
- * @typedef Callback
- *
- * Provides the callback necessary for async calling.
- */
- typedef std::function<void ( QVariant ) > Callback;
+ friend class Module;
+
+public:
/**
* @enum Type
@@ -65,13 +59,13 @@ class Call : public QObject
enum Type {
TypeUndefined = 0x0000, // Undefined call. Don't bother with.
- TypeResponse = 0x0001, // Represents a invoking call being responsed to.
- TypeDispatch = 0x0002, // Represents a invoked call being sent to.
- TypeSignal = 0x0003, // Represents a invoking signal being raised.
+ TypeResponse = 0x0010, // Represents a invoking call being responsed to.
+ TypeDispatch = 0x0011, // Represents a invoked call being sent to.
+ TypeSignal = 0x0012, // Represents a invoking signal being raised.
- TypeInvocation = 0x0010, // Represents a call to be invoked.
- TypeRemoteNoAuth = 0x0100, // This call deals with a remote network with no authentication.
- TypeRemoteAuth = 0x0200, // This call deals with a remote network with authentication.
+ TypeInvocation = 0x0020, // Represents a call to be invoked.
+ TypeRemoteNoAuth = 0x0021, // This call deals with a remote network with no authentication.
+ TypeRemoteAuth = 0x0022, // This call deals with a remote network with authentication.
TypeUser = 0x1000 // Anything above this is available to the user space.
};
@@ -127,12 +121,6 @@ class Call : public QObject
void setRecipient ( const QString moduleName );
/**
- * @fn invoke
- * @param data A list of QVariant variables.
- */
- QVariant invoke ( const QVariantList& data = QVariantList() );
-
- /**
* @operator operator()
* @brief Allow for functor-like capabilities for the Call object.
*/
@@ -145,4 +133,4 @@ typedef QSharedPointer<Call> CallPointer;
} /* Procedure */
} /* Wintermute */
-#endif /* WINTERMUTE_CORE_PROCEDURE_CALL_HPP */
+#endif /* WINTERMUTE_PROCEDURE_CALL_HPP */
View
6 src/Wintermute/Procedure/dummy_dispatcher.cpp
@@ -30,14 +30,15 @@ using Wintermute::Procedure::ReceiverPrivate;
DummyDispatcher::DummyDispatcher() :
Dispatcher()
{
- wdebug ( this, "Hey, I'm a dummy." );
+ setParent(wntrApp);
}
void
DummyDispatcher::sendMessage ( const Call* call )
{
wdebug ( this,
- QString ( "Sending out %1 bytes for dispatching..." ).arg ( call->toString().length() ) );
+ QString ( "Sending out %1 bytes for dispatching..." ).
+ arg ( call->toString().length() ) );
DummyReceiver* ds =
( static_cast<DummyReceiver*> ( ReceiverPrivate::receivers[0] ) );
ds->receiveMessage ( call );
@@ -45,5 +46,4 @@ DummyDispatcher::sendMessage ( const Call* call )
DummyDispatcher::~DummyDispatcher()
{
- wdebug ( this, "Hey, this dummy is gone!" );
}
View
3  src/Wintermute/Procedure/dummy_receiver.cpp
@@ -27,12 +27,13 @@ using Wintermute::Procedure::ReceiverPrivate;
DummyReceiver::DummyReceiver() :
Receiver()
{
+ setParent(wntrApp);
}
void
DummyReceiver::receiveMessage ( const Call* call )
{
- wdebug ( this, QString ( "We got %1 from %2" ).
+ wdebug ( this, QString ( "We got '%1' from '%2'." ).
arg ( call->toString(), call->recipient() ) );
Receiver::receiveMessage ( call );
}
View
32 src/Wintermute/Procedure/lambda_call.cpp
@@ -16,24 +16,44 @@
* along with Wintermute. If not, see <http://www.gnu.org/licenses/>.
**/
+#include "Wintermute/logging.hpp"
#include "Wintermute/application.hpp"
#include "Wintermute/Procedure/lambda_call.hpp"
#include "Wintermute/private/Procedure/call.hpp"
using Wintermute::Procedure::LambdaCall;
-LambdaCall::LambdaCall ( Call::Signature lambda, QString name ) :
+LambdaCall::LambdaCall ( const QString& name, Signature lambda ) :
Call ( Wintermute::Application::instance() )
{
Q_D ( Call );
- this->setProperty ( "name", name );
- d->function = lambda;
+ d->name = name;
}
-QString
-LambdaCall::name() const
+LambdaCall::Signature
+LambdaCall::function() const
{
- return this->property ( "name" ).toString();
+ return m_function;
+}
+
+void
+LambdaCall::setFunction(Signature newFunction)
+{
+ m_function = newFunction;
+}
+
+QVariant
+LambdaCall::invoke ( const QVariantList& data )
+{
+ if ( m_function != nullptr )
+ {
+ return m_function ( data );
+ }
+ else
+ {
+ winfo ( this, "Null function reference." );
+ return QVariant ();
+ }
}
LambdaCall::~LambdaCall()
View
19 src/Wintermute/Procedure/lambda_call.hpp
@@ -16,9 +16,10 @@
* along with Wintermute. If not, see <http://www.gnu.org/licenses/>.
**/
-#ifndef WINTERMUTE_CORE_PROCEDURE_LAMBDA_CALL_HPP
-#define WINTERMUTE_CORE_PROCEDURE_LAMBDA_CALL_HPP
+#ifndef WINTERMUTE_PROCEDURE_LAMBDA_CALL_HPP
+#define WINTERMUTE_PROCEDURE_LAMBDA_CALL_HPP
+#include <functional>
#include <Wintermute/Procedure/Call>
namespace Wintermute
@@ -28,9 +29,19 @@ namespace Procedure
class LambdaCall : public Call
{
public:
- explicit LambdaCall ( Call::Signature lambda, QString name );
+ /**
+ * @typedef Signature
+ * @brief Provides the short-hand signature for Call methods.
+ */
+ typedef std::function<QVariant ( QVariantList ) > Signature;
+
+ explicit LambdaCall ( const QString& name, Signature lambda );
virtual ~LambdaCall();
- virtual QString name() const;
+ Signature function() const;
+ void setFunction ( Signature newFunction );
+ QVariant invoke ( const QVariantList& data = QVariantList() );
+private:
+ Signature m_function;
};
}
}
View
45 src/Wintermute/Procedure/method_call.cpp
@@ -24,7 +24,9 @@
using Wintermute::Procedure::MethodCall;
using Wintermute::Procedure::Call;
-MethodCall::MethodCall ( const QString& module, const QString& method, const QVariantList arguments ) :
+MethodCall::MethodCall ( const QString& module,
+ const QString& method,
+ const QVariantList arguments ) :
Call ( new MethodCallPrivate ( this ) )
{
Q_D ( MethodCall );
@@ -34,6 +36,27 @@ MethodCall::MethodCall ( const QString& module, const QString& method, const QVa
d->data["arguments"] = arguments;
}
+void
+MethodCall::setArguments ( const QVariantList& arguments)
+{
+ Q_D ( MethodCall );
+ d->data.insert ( "arguments", arguments );
+}
+
+void
+MethodCall::setMethod ( const QString& method )
+{
+ Q_D ( MethodCall );
+ d->data.insert ( "method", method );
+}
+
+void
+MethodCall::setModule ( const QString& module )
+{
+ Q_D ( MethodCall );
+ d->data.insert ( "module", module );
+}
+
QVariantList
MethodCall::arguments() const
{
@@ -41,15 +64,25 @@ MethodCall::arguments() const
return d->data.value ( "arguments" ).toList();
}
+QString
+MethodCall::method() const
+{
+ Q_D ( const MethodCall );
+ return d->data.value ( "method" ).toString();
+}
+
+QString
+MethodCall::module() const
+{
+ Q_D ( const MethodCall );
+ return d->data.value ( "module" ).toString();
+}
+
void
MethodCall::dispatch ( Module* module )
{
Q_D ( MethodCall );
- QMap<QString, QVariant> appData;
- appData["pid"] = QCoreApplication::applicationPid();
- appData["version"] = QCoreApplication::applicationVersion();
- appData["module"] = module->qualifiedName();
- d->data["sender"] = appData;
+ d->composeMethodData( module );
module->dispatch ( *this );
}
View
17 src/Wintermute/Procedure/method_call.hpp
@@ -16,8 +16,8 @@
* along with Wintermute. If not, see <http://www.gnu.org/licenses/>.
**/
-#ifndef WINTERMUTE_CORE_PROCEDURE_METHOD_CALL_HPP
-#define WINTERMUTE_CORE_PROCEDURE_METHOD_CALL_HPP
+#ifndef WINTERMUTE_PROCEDURE_METHOD_CALL_HPP
+#define WINTERMUTE_PROCEDURE_METHOD_CALL_HPP
#include <QtCore/QObject>
#include <Wintermute/Procedure/Call>
@@ -39,6 +39,9 @@ class MethodCall : public Call
Q_OBJECT;
Q_DISABLE_COPY ( MethodCall );
Q_DECLARE_PRIVATE ( MethodCall );
+ Q_PROPERTY(QVariantList Arguments READ arguments WRITE setArguments);
+ Q_PROPERTY(QString Method READ method WRITE setMethod);
+ Q_PROPERTY(QString Module READ module WRITE setModule);
public:
/**
@@ -47,8 +50,10 @@ class MethodCall : public Call
* Crafts a call that can be used to invoke a remote method over the
* network.
*/
- explicit MethodCall ( const QString& module, const QString& method,
- const QVariantList arguments = QVariantList() );
+ explicit MethodCall (
+ const QString& module = QString::null,
+ const QString& method = QString::null,
+ const QVariantList arguments = QVariantList() );
/**
* @dtor
@@ -60,12 +65,16 @@ class MethodCall : public Call
* @brief The arguments to pass over the wire.
*/
QVariantList arguments() const;
+ QString module() const;
+ QString method() const;
/**
* @fn setArguments
* @brief Sets the arguments to use for this call.
*/
void setArguments ( const QVariantList& arguments );
+ void setModule ( const QString& module );
+ void setMethod ( const QString& method );
/**
* @fn dispatch
View
48 src/Wintermute/Procedure/module.cpp
@@ -36,37 +36,61 @@ Module::dispatch ( const Call& call ) const
{
Q_D ( const Module );
const QString callStr = call.toString();
- winfo ( this, QString ( "Sending '%1' to '%2'..." ).arg ( callStr, call.recipient() ) );
+ winfo ( this, QString ( "Sending '%1' to '%2'..." )
+ .arg ( callStr, call.recipient() ) );
d->sendData ( callStr );
return QVariant();
}
QVariant
-Module::invoke ( const QString callName, const QVariantList data )
+Module::invoke ( const QString callName,
+ const QVariantList data )
{
Q_D ( Module );
- if ( !d->calls.contains ( callName ) ) {
+ QVariant result;
+ if ( !d->calls.contains ( callName ) )
+ {
werr ( this, QString ( "The call '%1' doesn't exist in the module '%2'." )
- .arg ( callName, qualifiedName() ) );
- return QVariant ( -1 );
+ .arg ( callName, qualifiedName() ) );
+ return result;
}
- CallPointer call = d->calls[callName];
- return call->invoke ( data );
+
+ CallPointer callPtr = d->calls[callName];
+ Call* call = nullptr;
+ if ( callPtr.isNull() )
+ {
+ werr ( this, QString ("Attempted to invoke a null call '%1'.")
+ .arg( callName ) );
+ return result;
+ }
+
+ call = callPtr.data();
+ result = call->operator()( data );
+ return result;
}
void
Module::mount ( CallPointer call )
{
Q_D ( Module );
- // TODO: Use a shared pointer to prevent a segfault.
- d->calls[call->name()].swap ( call );
+ if ( d->calls.contains( call->name() ) )
+ {
+ winfo ( this, QString( "Updating call %1 to %2..." )
+ .arg( call->name(), domain() + "." + package() ) );
+ d->calls.remove ( call->name() );
+ }
+
+ winfo ( this, QString( "Adding call %1 to %2..." )
+ .arg( call->name(), domain() + "." + package() ) );
+ d->calls.insert ( call->name(), call );
}
LambdaCall*
-Module::mountLambda ( Call::Signature lambda, const QString& name )
+Module::mountLambda ( const QString& name,
+ LambdaCall::Signature lambda )
{
- CallPointer call = CallPointer ( new LambdaCall ( lambda, name ) );
- this->mount ( call );
+ CallPointer call ( new LambdaCall ( name, lambda ) );
+ mount ( call );
return dynamic_cast<LambdaCall*> ( call.data() );
}
View
28 src/Wintermute/Procedure/module.hpp
@@ -25,6 +25,7 @@
#include <QtCore/QString>
#include <QtCore/QObject>
#include <QtCore/QScopedPointer>
+#include <Wintermute/Globals>
#include <Wintermute/Procedure/Call>
#include <Wintermute/Procedure/LambdaCall>
@@ -64,6 +65,9 @@ class Module : public QObject
/**
* @fn qualifiedName
+ *
+ * The fully formed version of the Module's name (typically a joining of the
+ * domain and package).
*/
QString qualifiedName() const;
@@ -75,13 +79,32 @@ class Module : public QObject
/**
* @fn start
+ * @brief Starts the worker logic for this module.
+ *
+ * Use this method to invoke the starting up processes of this Module and
+ * start its chugging.
*/
Q_SLOT virtual void start() = 0;
+ /**
+ * @fn stop
+ * @brief Halts the worker logic for this module.
+ *
+ * Use this method to cancel pending tasks and bring the purpose of this
+ * Module to a full stop.
+ */
+ Q_SLOT virtual void stop() = 0;
+
protected:
/**
* @fn invoke
* @brief Looks for the named call and invoke with the provided data.
+ *
+ * Handles the act of invocation of the named call and provides it with the
+ * necessary work to invoke it.
+ *
+ * @note This currently doesn't consider spawning a new thread to handle this
+ * working process. A separate method will consider this.
*/
QVariant invoke ( const QString name, const QVariantList data = QVariantList() );
@@ -108,9 +131,12 @@ class Module : public QObject
* @brief Crafts a LambdaCall out of a function pointer and adds the
* call into the system.
*/
- LambdaCall* mountLambda ( Call::Signature lambda, const QString& name );
+ LambdaCall* mountLambda ( const QString& name,
+ LambdaCall::Signature lambdaFunction );
};
} /* Procedure */
} /* Wintermute */
+Q_DECLARE_INTERFACE(Wintermute::Procedure::Module, "in.wintermute.procedure.module/0.1.0");
+
#endif /* WINTERMUTE_CORE_PROCEDURE_MODULE_HPP */
View
22 src/Wintermute/Procedure/process_module.cpp
@@ -16,7 +16,8 @@
* along with Wintermute. If not, see <http://www.gnu.org/licenses/>.
**/
-#include "Wintermute/Globals"
+#include <QtCore/QCoreApplication>
+#include <Wintermute/Globals>
#include "Wintermute/logging.hpp"
#include "Wintermute/Procedure/process_module.hpp"
#include "Wintermute/Procedure/process_module.moc"
@@ -25,26 +26,33 @@ using Wintermute::Procedure::ProcessModule;
ProcessModule::ProcessModule() : Module ( Wintermute::Application::instance() )
{
- setDomain ( WINTERMUTE_DOMAIN );
+ setDomain ( WINTERMUTE_DOMAIN );
setPackage ( "process" );
- connect ( wntrApp, SIGNAL ( started() ), SLOT ( start() ) );
}
void
ProcessModule::start()
{
- // TODO: What?
- winfo ( this, QString ( "Currently %1 modules loaded so far." ).arg ( wntrApp->modules().length() ) );
+ connect ( wntrApp, SIGNAL ( started() ), SLOT ( start() ) );
+ winfo ( this, QString ( "Currently %1 modules loaded so far." )
+ .arg ( wntrApp->modules().length() ) );
+ // TODO: Move the mode handling logic here?
}
void
ProcessModule::reboot()
{
- // TODO: Add forking logic or recycle some.
Wintermute::Application::instance()->stop();
}
void
+ProcessModule::stop()
+{
+ winfo ( this, QString ("Stopping Wintermute...") );
+ quit ();
+}
+
+void
ProcessModule::quit ( const int exitcode )
{
winfo ( this, "Invoking remote exit..." );
@@ -53,4 +61,6 @@ ProcessModule::quit ( const int exitcode )
ProcessModule::~ProcessModule()
{
+ if ( !QCoreApplication::closingDown() )
+ stop();
}
View
7 src/Wintermute/Procedure/process_module.hpp
@@ -16,11 +16,12 @@
* along with Wintermute. If not, see <http://www.gnu.org/licenses/>.
**/
-#ifndef WINTERMUTE_CORE_PROCEDURE_PROCESS_MODULE_HPP
-#define WINTERMUTE_CORE_PROCEDURE_PROCESS_MODULE_HPP
+#ifndef WINTERMUTE_PROCEDURE_PROCESS_MODULE_HPP
+#define WINTERMUTE_PROCEDURE_PROCESS_MODULE_HPP
#include <Wintermute/Application>
#include <Wintermute/Procedure/Module>
+#include "module.hpp"
namespace Wintermute
{
@@ -37,6 +38,7 @@ class ProcessModule : public Module
{
Q_OBJECT;
Q_DISABLE_COPY ( ProcessModule );
+ Q_INTERFACES (Wintermute::Procedure::Module);
friend class Wintermute::ApplicationPrivate;
explicit ProcessModule();
@@ -44,6 +46,7 @@ class ProcessModule : public Module
public:
virtual ~ProcessModule();
Q_SLOT virtual void start();
+ Q_SLOT virtual void stop();
protected:
void reboot();
View
25 lib/heartbeat/calls/greet.hpp → src/Wintermute/Procedure/reply_call.hpp
@@ -1,6 +1,6 @@
/**
* vim: ft=cpp tw=78
- * Copyright (C) 2013 Jacky Alciné <me@jalcine.me>
+ * Copyright (C) 2014 Jacky Alciné <me@jalcine.me>
*
* Wintermute is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -16,20 +16,15 @@
* along with Wintermute. If not, see <http://www.gnu.org/licenses/>.
**/
-#ifndef WINTERMUTE_HEARTBEAT_CALLS_GREET
-#define WINTERMUTE_HEARTBEAT_CALLS_GREET
-
#include <Wintermute/Procedure/Call>
-namespace Wintermute
-{
-namespace Heartbeat
-{
-class GreetCall : public Wintermute::Procedure::Call
-{
- Q_OBJECT;
-};
-}
+namespace Wintermute {
+ namespace Procedure {
+ /***
+ *
+ */
+ class ReplyCall : public Call {
+ Q_OBJECT;
+ };
+ }
}
-
-#endif /** WINTERMUTE_HEARTBEAT_CALLS_GREET */
View
50 src/Wintermute/application.cpp
@@ -1,6 +1,6 @@
/**
* vim: ft=cpp tw=78
- * Copyright (C) 2011 - 2013 Jacky Alciné <me@jalcine.me>
+ * Copyright (C) 2011, 2012, 2013, 2014 Jacky Alciné <me@jalcine.me>
*
* Wintermute is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -18,6 +18,7 @@
#include <QtCore/QCoreApplication>
#include <QtCore/QDebug>
+#include <QtCore/QDateTime>
#include <QtCore/QSharedPointer>
#include "application.hpp"
#include "version.hpp"
@@ -39,28 +40,35 @@ Application::Application ( int& argc, char** argv ) :
{
Q_D ( Application );
Application::self = qobject_cast<Application*> ( this );
- d->app->setApplicationName ( WINTERMUTE_NAME );
+ d->app->setApplicationName ( WINTERMUTE_NAME );
d->app->setApplicationVersion ( this->version().toString() );
- d->app->setOrganizationName ( WINTERMUTE_NAME );
+ d->app->setOrganizationName ( WINTERMUTE_NAME );
d->app->setOrganizationDomain ( WINTERMUTE_DOMAIN );
d->settings = new QSettings;
+ d->settings->setValue( "Timing/StartupTime" ,
+ QDateTime::currentDateTimeUtc().toString() );
+
+ winfo(this, QString( "Wintermute recorded startup at %1." )
+ .arg( d->settings->value( "Timing/StartupTime" ).toString() ) );
}
int
Application::run ( int& argc, char** argv )
{
int returnCode = -1;
- if ( Application::instance() == 0 ) {
+
+ if ( Application::instance() == 0 )
+ {
Application::self = new Application ( argc, argv );
Logger* log = wlog ( Application::self );
self->d_ptr->initialize();
log->info ( QString ( "Wintermute is starting; PID %1. Let's play." ).
- arg ( QCoreApplication::applicationPid() ) );
+ arg ( QCoreApplication::applicationPid() ) );
self->start();
log->debug ( "Starting event loop." );
returnCode = self->d_ptr->exec();
log->info ( "Event loop ended; ended with" +
- QString ( "exit code %1" ).arg ( returnCode ) );
+ QString ( "exit code %1" ).arg ( returnCode ) );
}
return returnCode;
}
@@ -87,8 +95,9 @@ Application::stop ( int exitcode )
QCoreApplication::quit();
emit this->stopped();
log->info ( "Wintermute is stopping " + QString ( "with exit code %1." )
- .arg ( exitcode ) );
- if ( QCoreApplication::startingUp() || QCoreApplication::closingDown() ) {
+ .arg ( exitcode ) );
+ if ( QCoreApplication::startingUp() || QCoreApplication::closingDown() )
+ {
exit ( exitcode );
}
}
@@ -97,7 +106,8 @@ QString
Application::processName() const
{
Q_D ( const Application );
- if ( !d->module ) {
+ if ( !d->module )
+ {
return QString::null;
}
return d->module->qualifiedName();
@@ -113,12 +123,12 @@ Application::modules() const
Module*
Application::findModule ( const QString& name ) const
{
- // NOTE: This could be so much more functional.
Q_D ( const Application );
- Q_FOREACH ( Module * mod, d->modules ) {
- if ( mod->domain().contains ( name ) ) {
- return mod;
- }
+ winfo(this, QString("Searching for %1 in this instance...").arg(name));
+ Q_FOREACH ( Module * mod, d->modules )
+ {
+ QString fullPath = mod->domain() + "." + mod->package();
+ if ( fullPath == name ) { return mod; }
}
return nullptr;
}
@@ -130,17 +140,18 @@ Application::version() const
ver.major = WINTERMUTE_VERSION_MAJOR;
ver.minor = WINTERMUTE_VERSION_MINOR;
ver.patch = WINTERMUTE_VERSION_PATCH;
- ver.state = ( Wintermute::Version::DevelopmentStage ) WINTERMUTE_VERSION_STAGE;
- ver.stage = QString ( "%1:%2" ).arg ( WINTERMUTE_VERSION_STAGE_REF, WINTERMUTE_VERSION_STAGE_BRANCH );
+ ver.state = ( Wintermute::Version::DevelopmentStage )
+ WINTERMUTE_VERSION_STAGE;
+ ver.stage = QString ( "%1-%2" ).arg ( WINTERMUTE_VERSION_STAGE_REF,
+ WINTERMUTE_VERSION_STAGE_BRANCH );
return ver;
}
QVariant
-Application::setting ( const QString& path, const QVariant defaultValue )
+Application::setting ( const QString& path, const QVariant value )
{
ApplicationPrivate* d = Application::instance()->d_ptr.data();
- d->settings->contains ( path ) ? d->settings->value ( path ) : defaultValue;
- return defaultValue;
+ return d->settings->contains ( path ) ? d->settings->value ( path ) : value;
}
void
@@ -148,6 +159,7 @@ Application::setSetting ( const QString& path, const QVariant value )
{
ApplicationPrivate* d = Application::instance()->d_ptr.data();
d->settings->setValue ( path, value );
+ d->settings->sync();
}
Application::~Application()
View
29 src/Wintermute/application.hpp
@@ -23,6 +23,14 @@
#include <QtCore/QList>
#include <Wintermute/Globals>
+/**
+ * @constant wntrApp
+ * @brief Shorthand for Wintermute::Application.
+ *
+ * Allows for quick access to the singleton instance of Wintermute.