ソースを参照

Added "code snippet" support.

The ctkFunctionCompileSnippets CMake function can be used to compile
code snippets in a given directory. This is useful for including
code in doxygen files which is certain to compile.

Added one snippet for an Event Admin introduction.
Sascha Zelzer 13 年 前
コミット
4369ec706e

+ 65 - 0
CMake/ctkFunctionCompileSnippets.cmake

@@ -0,0 +1,65 @@
+
+#! Compile code snippets from a given directory
+#!
+#! This CMake function globs all files called \e main.cpp in the
+#! directory given by <code>snippet_path</code> and creates
+#! an executable for each found main.cpp.
+#!
+#! If a \e files.cmake file exists in the same directory where a
+#! main.cpp file was found, it is included. This function assumes
+#! that the files.cmake file sets a list named \e snippet_src_files
+#! containing a list of files which should be compiled into the
+#! executable. If no files.cmake file is found, all files in the
+#! directory are compiled into the executable.
+#!
+#! This function uses all additionally passed arguments as link
+#! dependencies for the created executable.
+#!
+function(ctkFunctionCompileSnippets snippet_path)
+
+  # get all files called "main.cpp"
+  file(GLOB_RECURSE main_cpp_list "${snippet_path}/main.cpp")
+
+  foreach(main_cpp_file ${main_cpp_list})
+    # get the directory containing the main.cpp file
+    get_filename_component(main_cpp_dir "${main_cpp_file}" PATH)
+    
+    set(snippet_src_files )
+    
+    # If there exists a "files.cmake" file in the snippet directory,
+    # include it and assume it sets the variable "snippet_src_files"
+    # to a list of source files for the snippet.
+    if(EXISTS "${main_cpp_dir}/files.cmake")
+      include("${main_cpp_dir}/files.cmake")
+      set(_tmp_src_files ${snippet_src_files})
+      set(snippet_src_files )
+      foreach(_src_file ${_tmp_src_files})
+        if(IS_ABSOLUTE ${_src_file})
+          list(APPEND snippet_src_files ${_src_file})
+        else()
+          list(APPEND snippet_src_files ${main_cpp_dir}/${_src_file})
+        endif()
+      endforeach()
+    else()
+      # glob all files in the directory and add them to the snippet src list
+      file(GLOB_RECURSE snippet_src_files "${main_cpp_dir}/*")
+    endif()
+    
+    # Uset the top-level directory name as the executable name
+    string(REPLACE "/" ";" main_cpp_dir_tokens "${main_cpp_dir}")
+    list(GET main_cpp_dir_tokens -1 snippet_exec_name)
+    set(snippet_target_name "Snippet-${snippet_exec_name}")
+    add_executable(${snippet_target_name} ${snippet_src_files})
+    if(ARGN)
+      target_link_libraries(${snippet_target_name} ${ARGN})
+    endif()
+    set_target_properties(${snippet_target_name} PROPERTIES
+      RUNTIME_OUTPUT_DIRECTORY "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/snippets"
+      ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_ARCHIVE_OUTPUT_DIRECTORY}/snippets"
+      LIBRARY_OUTPUT_DIRECTORY "${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/snippets"
+      OUTPUT_NAME ${snippet_exec_name}
+    )
+    
+  endforeach()
+
+endfunction()

+ 1 - 0
CMakeLists.txt

@@ -199,6 +199,7 @@ include(CMake/ctkFunctionCheckCompilerFlags.cmake)
 include(CMake/ctkFunctionGetIncludeDirs.cmake)
 include(CMake/ctkFunctionGetLibraryDirs.cmake)
 include(CMake/ctkFunctionGetGccVersion.cmake)
+include(CMake/ctkFunctionCompileSnippets.cmake)
 
 #-----------------------------------------------------------------------------
 # Testing

+ 2 - 1
Documentation/Doxyfile.txt.in

@@ -705,6 +705,7 @@ EXCLUDE_PATTERNS       = moc_*.cxx \
                          */Testing/* \
                          */Utilities/* \
                          */Widgets/Plugins/* \
+                         */Snippets/* \
                          @CTK_ADDITIONAL_EXCLUDE_PATTERN@
 
 # The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names
@@ -719,7 +720,7 @@ EXCLUDE_SYMBOLS        =
 # directories that contain example code fragments that are included (see
 # the \include command).
 
-EXAMPLE_PATH           =
+EXAMPLE_PATH           = @CTK_SOURCE_DIR@/Libs/PluginFramework/Documentation/Snippets/
 
 # If the value of the EXAMPLE_PATH tag contains directories, you can use the
 # EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp

+ 4 - 0
Libs/PluginFramework/CMakeLists.txt

@@ -162,4 +162,8 @@ endif()
 # Testing
 if(BUILD_TESTING)
   add_subdirectory(Testing)
+
+  # Compile source code snippets
+  add_subdirectory(Documentation/Snippets)
+
 endif()

+ 4 - 0
Libs/PluginFramework/Documentation/Snippets/CMakeLists.txt

@@ -0,0 +1,4 @@
+if(BUILD_TESTING)
+  include_directories(${CTKPluginFramework_SOURCE_DIR})
+  ctkFunctionCompileSnippets("${CMAKE_CURRENT_SOURCE_DIR}" CTKPluginFramework)
+endif()

+ 157 - 0
Libs/PluginFramework/Documentation/Snippets/EventAdmin-Intro/ctkSnippetReportManager.h

@@ -0,0 +1,157 @@
+/*=============================================================================
+
+  Library: CTK
+
+  Copyright (c) German Cancer Research Center,
+    Division of Medical and Biological Informatics
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+
+=============================================================================*/
+
+
+#ifndef CTKSNIPPETREPORTMANAGER_H
+#define CTKSNIPPETREPORTMANAGER_H
+
+#include <ctkPluginContext.h>
+#include <ctkServiceReference.h>
+
+#include <service/event/ctkEventAdmin.h>
+#include <service/event/ctkEventHandler.h>
+
+#include <ctkPluginFrameworkLauncher.h>
+
+#include <QTime>
+
+class Report
+{
+public:
+  QString getTitle() const { return "dummy"; }
+  QString getAbsolutePath() const { return "dummy"; }
+};
+
+//! [Event Handler service]
+class ReportEventHandler : public QObject, public ctkEventHandler
+{
+  Q_OBJECT
+  Q_INTERFACES(ctkEventHandler)
+
+public:
+
+  void handleEvent(const ctkEvent& event)
+  {
+    QString reportTitle = event.getProperty("title").toString();
+    QString reportPath = event.getProperty("path").toString();
+
+    // sendReportByEmail(reportTitle, reportPath);
+    qDebug() << "title:" << reportTitle << "path:" << reportPath;
+  }
+};
+//! [Event Handler service]
+
+//! [Event Handler slot]
+class ReportEventHandlerUsingSlots : public QObject
+{
+  Q_OBJECT
+
+public slots:
+
+  void handleEvent(const ctkEvent& event)
+  {
+    QString reportTitle = event.getProperty("title").toString();
+    QString reportPath = event.getProperty("path").toString();
+
+    // sendReportByEmail(reportTitle, reportPath);
+    qDebug() << "[slot] title:" << reportTitle << "path:" << reportPath;
+  }
+};
+//! [Event Handler slot]
+
+class ReportManager : public QObject
+{
+  Q_OBJECT
+
+public:
+
+  //! [Register signal]
+  ReportManager(ctkPluginContext* context)
+  {
+    ctkServiceReference ref = context->getServiceReference<ctkEventAdmin>();
+    if (ref)
+    {
+      ctkEventAdmin* eventAdmin = context->getService<ctkEventAdmin>(ref);
+      // Using Qt::DirectConnection is equivalent to ctkEventAdmin::sendEvent()
+      eventAdmin->publishSignal(this, SIGNAL(reportGeneratedSignal(ctkDictionary)),
+                                "com/acme/reportgenerator/GENERATED", Qt::DirectConnection);
+    }
+  }
+  //! [Register signal]
+
+  //! [Emit signal]
+  void reportGenerated(const Report& report)
+  {
+    ctkDictionary properties;
+    properties["title"] = report.getTitle();
+    properties["path"] = report.getAbsolutePath();
+    properties["time"] = QTime::currentTime();
+    emit reportGeneratedSignal(properties);
+  }
+  //! [Emit signal]
+
+  //! [Publish event]
+  void reportGenerated(const Report& report, ctkPluginContext* context)
+  {
+    ctkServiceReference ref = context->getServiceReference<ctkEventAdmin>();
+    if (ref)
+    {
+      ctkEventAdmin* eventAdmin = context->getService<ctkEventAdmin>(ref);
+
+      ctkDictionary properties;
+      properties["title"] = report.getTitle();
+      properties["path"] = report.getAbsolutePath();
+      properties["time"] = QTime::currentTime();
+
+      ctkEvent reportGeneratedEvent("com/acme/reportgenerator/GENERATED", properties);
+      eventAdmin->sendEvent(reportGeneratedEvent);
+    }
+  }
+  //! [Publish event]
+
+  void reportGeneratedAsync(const Report& report, ctkPluginContext* context)
+  {
+    ctkServiceReference ref = context->getServiceReference<ctkEventAdmin>();
+    if (ref)
+    {
+      ctkEventAdmin* eventAdmin = context->getService<ctkEventAdmin>(ref);
+
+      ctkDictionary properties;
+      properties["title"] = report.getTitle();
+      properties["path"] = report.getAbsolutePath();
+      properties["time"] = QTime::currentTime();
+
+      //! [Publish event async]
+      ctkEvent reportGeneratedEvent("com/acme/reportgenerator/GENERATED", properties);
+      eventAdmin->postEvent(reportGeneratedEvent);
+      //! [Publish event async]
+    }
+  }
+
+  //! [Declare signal]
+signals:
+
+  void reportGeneratedSignal(const ctkDictionary&);
+  //! [Declare signal]
+
+};
+
+#endif // CTKSNIPPETREPORTMANAGER_H

+ 13 - 0
Libs/PluginFramework/Documentation/Snippets/EventAdmin-Intro/files.cmake

@@ -0,0 +1,13 @@
+set(snippet_src_files
+  main.cpp
+  ctkSnippetReportManager.h
+)
+
+set(_moc_files
+  ctkSnippetReportManager.h
+)
+
+foreach(_moc_file ${_moc_files})
+  QT4_WRAP_CPP(snippet_src_files EventAdmin-Intro/${_moc_file}
+               OPTIONS -f${CMAKE_CURRENT_SOURCE_DIR}/EventAdmin-Intro/${_moc_file})
+endforeach()

+ 64 - 0
Libs/PluginFramework/Documentation/Snippets/EventAdmin-Intro/main.cpp

@@ -0,0 +1,64 @@
+
+#include <ctkPluginConstants.h>
+#include <service/event/ctkEventConstants.h>
+
+#include <QCoreApplication>
+#include <QDir>
+
+#include "ctkSnippetReportManager.h"
+
+// dummy main
+int main(int argc, char** argv)
+{
+  QCoreApplication myApp(argc, argv);
+
+  QString tmpPath = QDir::tempPath() + "/snippet-eventadmin-intro";
+  ctkProperties fwProps;
+  fwProps[ctkPluginConstants::FRAMEWORK_STORAGE] = tmpPath;
+  fwProps[ctkPluginConstants::FRAMEWORK_STORAGE_CLEAN] = ctkPluginConstants::FRAMEWORK_STORAGE_CLEAN_ONFIRSTINIT;
+  fwProps["org.commontk.pluginfw.debug.resolve"] = true;
+  fwProps["org.commontk.pluginfw.debug.service_reference"] = true;
+  fwProps["org.commontk.pluginfw.debug.errors"] = true;
+  fwProps["org.commontk.pluginfw.debug.pluginfw"] = true;
+  fwProps["org.commontk.pluginfw.debug.lazy_activation"] = true;
+  ctkPluginFrameworkLauncher::setFrameworkProperties(fwProps);
+  ctkPluginFrameworkLauncher::start("org.commontk.eventadmin");
+
+  ctkPluginContext* pluginContext = ctkPluginFrameworkLauncher::getPluginContext();
+
+  ReportManager reportManager(pluginContext);
+
+  //! [Event Handler service registration]
+  ReportEventHandler eventHandler;
+  ctkDictionary props;
+  props[ctkEventConstants::EVENT_TOPIC] = "com/acme/reportgenerator/GENERATED";
+  pluginContext->registerService<ctkEventHandler>(&eventHandler, props);
+  //! [Event Handler service registration]
+
+  // You can also use a wildcard in the final character of the EVENT_TOPIC
+  //! [Event Handler service registration wildcard]
+  props[ctkEventConstants::EVENT_TOPIC] = "com/acme/reportgenerator/*";
+  pluginContext->registerService<ctkEventHandler>(&eventHandler, props);
+  //! [Event Handler service registration wildcard]
+
+  // Or you could use a filter expression (using LDAP syntax)
+  //! [Event Handler service registration filter]
+  props[ctkEventConstants::EVENT_TOPIC] = "com/acme/reportgenerator/GENERATED";
+  props[ctkEventConstants::EVENT_FILTER] = "(title=samplereport)";
+  pluginContext->registerService<ctkEventHandler>(&eventHandler, props);
+  //! [Event Handler service registration filter]
+
+  //! [Event Handler service registration slot]
+  ReportEventHandlerUsingSlots eventHandlerUsingSlots;
+  ctkDictionary propsForSlot;
+  propsForSlot[ctkEventConstants::EVENT_TOPIC] = "com/acme/reportgenerator/*";
+  ctkServiceReference ref = pluginContext->getServiceReference<ctkEventAdmin>();
+  if (ref)
+  {
+    ctkEventAdmin* eventAdmin = pluginContext->getService<ctkEventAdmin>(ref);
+    eventAdmin->subscribeSlot(&eventHandlerUsingSlots, SLOT(handleEvent(ctkEvent)), propsForSlot);
+  }
+  //! [Event Handler service registration slot]
+
+  reportManager.reportGenerated(Report());
+}