From e9bd7e313c80ccdabc52757266177363c7638caf Mon Sep 17 00:00:00 2001 From: Stefan Radomski Date: Sat, 23 Mar 2013 00:35:31 +0100 Subject: Fixed plugins building again --- CMakeLists.txt | 23 +- src/uscxml/Factory.cpp | 2 +- src/uscxml/Interpreter.cpp | 9 +- src/uscxml/Interpreter.h | 6 +- src/uscxml/plugins/Plugins.cpp | 2 +- src/uscxml/plugins/Plugins.h | 2 +- src/uscxml/plugins/element/fetch/FetchElement.h | 2 +- .../plugins/element/postpone/PostponeElement.h | 2 +- .../plugins/element/response/ResponseElement.cpp | 2 +- .../plugins/element/response/ResponseElement.h | 2 +- src/uscxml/plugins/invoker/ffmpeg/FFMPEGInvoker.h | 2 +- .../invoker/filesystem/dirmon/DirMonInvoker.h | 2 +- .../filesystem/dirmon/FileWatcher/FileWatcher.cpp | 75 --- .../filesystem/dirmon/FileWatcher/FileWatcher.h | 141 ------ .../dirmon/FileWatcher/FileWatcherImpl.h | 77 --- .../dirmon/FileWatcher/FileWatcherLinux.cpp | 166 ------- .../dirmon/FileWatcher/FileWatcherLinux.h | 89 ---- .../dirmon/FileWatcher/FileWatcherOSX.cpp | 386 --------------- .../filesystem/dirmon/FileWatcher/FileWatcherOSX.h | 88 ---- .../dirmon/FileWatcher/FileWatcherWin32.cpp | 244 ---------- .../dirmon/FileWatcher/FileWatcherWin32.h | 83 ---- .../graphics/openscenegraph/OSGConverter.cpp | 533 --------------------- .../invoker/graphics/openscenegraph/OSGConverter.h | 82 ---- .../openscenegraph/converter/OSGConverter.cpp | 533 +++++++++++++++++++++ .../openscenegraph/converter/OSGConverter.h | 82 ++++ .../plugins/invoker/miles/MilesSessionInvoker.h | 2 +- src/uscxml/plugins/invoker/sample/SampleInvoker.h | 2 +- .../plugins/invoker/sqlite3/Sqlite3Invoker.h | 2 +- src/uscxml/plugins/invoker/system/SystemInvoker.h | 2 +- src/uscxml/server/InterpreterServlet.cpp | 34 ++ src/uscxml/server/InterpreterServlet.h | 46 ++ test/CMakeLists.txt | 2 +- 32 files changed, 741 insertions(+), 1984 deletions(-) delete mode 100644 src/uscxml/plugins/invoker/filesystem/dirmon/FileWatcher/FileWatcher.cpp delete mode 100644 src/uscxml/plugins/invoker/filesystem/dirmon/FileWatcher/FileWatcher.h delete mode 100644 src/uscxml/plugins/invoker/filesystem/dirmon/FileWatcher/FileWatcherImpl.h delete mode 100644 src/uscxml/plugins/invoker/filesystem/dirmon/FileWatcher/FileWatcherLinux.cpp delete mode 100644 src/uscxml/plugins/invoker/filesystem/dirmon/FileWatcher/FileWatcherLinux.h delete mode 100644 src/uscxml/plugins/invoker/filesystem/dirmon/FileWatcher/FileWatcherOSX.cpp delete mode 100644 src/uscxml/plugins/invoker/filesystem/dirmon/FileWatcher/FileWatcherOSX.h delete mode 100644 src/uscxml/plugins/invoker/filesystem/dirmon/FileWatcher/FileWatcherWin32.cpp delete mode 100644 src/uscxml/plugins/invoker/filesystem/dirmon/FileWatcher/FileWatcherWin32.h delete mode 100644 src/uscxml/plugins/invoker/graphics/openscenegraph/OSGConverter.cpp delete mode 100644 src/uscxml/plugins/invoker/graphics/openscenegraph/OSGConverter.h create mode 100644 src/uscxml/plugins/invoker/graphics/openscenegraph/converter/OSGConverter.cpp create mode 100644 src/uscxml/plugins/invoker/graphics/openscenegraph/converter/OSGConverter.h create mode 100644 src/uscxml/server/InterpreterServlet.cpp create mode 100644 src/uscxml/server/InterpreterServlet.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 2980fae..d861905 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -806,7 +806,8 @@ if (OPENSCENEGRAPH_FOUND AND OPENGL_FOUND) include_directories(${OPENSCENEGRAPH_INCLUDE_DIRS}) include_directories(${OPENGL_INCLUDE_DIR}) - file(GLOB_RECURSE OPENSCENEGRAPH_INVOKER + + file(GLOB OPENSCENEGRAPH_INVOKER src/uscxml/plugins/invoker/graphics/openscenegraph/*.cpp src/uscxml/plugins/invoker/graphics/openscenegraph/*.h) source_group("Invoker\\scenegraph" FILES ${OPENSCENEGRAPH_INVOKER}) @@ -824,6 +825,26 @@ if (OPENSCENEGRAPH_FOUND AND OPENGL_FOUND) list (APPEND USCXML_FILES ${OPENSCENEGRAPH_INVOKER}) list (APPEND USCXML_OPT_LIBS ${OPENSCENEGRAPH_LIBRARIES} ${OPENGL_LIBRARIES}) endif() + + file(GLOB OPENSCENEGRAPH_CONVERTER_INVOKER + src/uscxml/plugins/invoker/graphics/openscenegraph/converter/*.cpp + src/uscxml/plugins/invoker/graphics/openscenegraph/converter/*.h) + source_group("Invoker\\scenegraph\\convert" FILES ${OPENSCENEGRAPH_CONVERTER_INVOKER}) + + if (BUILD_AS_PLUGINS) + add_library( + invoker_openscenegraph_convert SHARED + ${OPENSCENEGRAPH_CONVERTER_INVOKER}) + target_link_libraries(invoker_openscenegraph_convert + ${OPENSCENEGRAPH_LIBRARIES} + ${OPENGL_LIBRARIES} + uscxml) + set_target_properties(invoker_openscenegraph_convert PROPERTIES FOLDER "Plugin Invoker") + else() + list (APPEND USCXML_FILES ${OPENSCENEGRAPH_CONVERTER_INVOKER}) + list (APPEND USCXML_OPT_LIBS ${OPENSCENEGRAPH_LIBRARIES} ${OPENGL_LIBRARIES}) + endif() + endif() if (UNIX) diff --git a/src/uscxml/Factory.cpp b/src/uscxml/Factory.cpp index 623b551..787e0ff 100644 --- a/src/uscxml/Factory.cpp +++ b/src/uscxml/Factory.cpp @@ -65,7 +65,7 @@ Factory::Factory() { pluma.acceptProviderType(); pluma.acceptProviderType(); pluma.acceptProviderType(); - pluma.acceptProviderType(); + pluma.acceptProviderType(); pluma.loadFromFolder(pluginPath); std::vector invokerProviders; diff --git a/src/uscxml/Interpreter.cpp b/src/uscxml/Interpreter.cpp index 0c466c9..0bc0f2e 100644 --- a/src/uscxml/Interpreter.cpp +++ b/src/uscxml/Interpreter.cpp @@ -206,7 +206,7 @@ void Interpreter::init() { normalize(_document); if (_capabilities & CAN_GENERIC_HTTP) - _httpServlet = new HTTPServletInvoker(this); + _httpServlet = new InterpreterServlet(this); _sendQueue = new DelayedEventQueue(); _sendQueue->start(); @@ -297,8 +297,11 @@ void Interpreter::interpret() { if (_dataModel) { _dataModel.assign("_x.args", _cmdLineOptions); - if (_httpServlet) - _dataModel.assign("_ioprocessors['http']", _httpServlet->getDataModelVariables()); + if (_httpServlet) { + Data data; + data.compound["location"] = Data(_httpServlet->getURL(), Data::VERBATIM); + _dataModel.assign("_ioprocessors['http']", data); + } } setupIOProcessors(); diff --git a/src/uscxml/Interpreter.h b/src/uscxml/Interpreter.h index 90c2b3b..9929f70 100644 --- a/src/uscxml/Interpreter.h +++ b/src/uscxml/Interpreter.h @@ -24,6 +24,8 @@ #include "uscxml/Message.h" #include "uscxml/Factory.h" +#include "uscxml/server/InterpreterServlet.h" + #define ORIG_ENTERSTATES namespace uscxml { @@ -120,7 +122,7 @@ public: return _cmdLineOptions; } - HTTPServletInvoker* getHTTPServlet() { + InterpreterServlet* getHTTPServlet() { return _httpServlet; } @@ -247,7 +249,7 @@ protected: Event _currEvent; - HTTPServletInvoker* _httpServlet; + InterpreterServlet* _httpServlet; std::set _monitors; diff --git a/src/uscxml/plugins/Plugins.cpp b/src/uscxml/plugins/Plugins.cpp index 65740e1..1f74a28 100644 --- a/src/uscxml/plugins/Plugins.cpp +++ b/src/uscxml/plugins/Plugins.cpp @@ -6,7 +6,7 @@ namespace uscxml { PLUMA_PROVIDER_SOURCE(DataModelImpl, 1, 1); PLUMA_PROVIDER_SOURCE(IOProcessorImpl, 1, 1); PLUMA_PROVIDER_SOURCE(InvokerImpl, 1, 1); -PLUMA_PROVIDER_SOURCE(ElementImpl, 1, 1); +PLUMA_PROVIDER_SOURCE(ExecutableContentImpl, 1, 1); #endif } \ No newline at end of file diff --git a/src/uscxml/plugins/Plugins.h b/src/uscxml/plugins/Plugins.h index 338dcaf..8b574b1 100644 --- a/src/uscxml/plugins/Plugins.h +++ b/src/uscxml/plugins/Plugins.h @@ -9,7 +9,7 @@ namespace uscxml { #ifdef BUILD_AS_PLUGINS PLUMA_PROVIDER_HEADER(IOProcessorImpl); PLUMA_PROVIDER_HEADER(InvokerImpl); -PLUMA_PROVIDER_HEADER(ElementImpl); +PLUMA_PROVIDER_HEADER(ExecutableContentImpl); PLUMA_PROVIDER_HEADER(DataModelImpl); #endif diff --git a/src/uscxml/plugins/element/fetch/FetchElement.h b/src/uscxml/plugins/element/fetch/FetchElement.h index aadbb7c..b553293 100644 --- a/src/uscxml/plugins/element/fetch/FetchElement.h +++ b/src/uscxml/plugins/element/fetch/FetchElement.h @@ -40,7 +40,7 @@ protected: }; #ifdef BUILD_AS_PLUGINS -PLUMA_INHERIT_PROVIDER(FetchElement, Element); +PLUMA_INHERIT_PROVIDER(FetchElement, ExecutableContentImpl); #endif } diff --git a/src/uscxml/plugins/element/postpone/PostponeElement.h b/src/uscxml/plugins/element/postpone/PostponeElement.h index 268493f..7886415 100644 --- a/src/uscxml/plugins/element/postpone/PostponeElement.h +++ b/src/uscxml/plugins/element/postpone/PostponeElement.h @@ -63,7 +63,7 @@ protected: }; #ifdef BUILD_AS_PLUGINS -PLUMA_INHERIT_PROVIDER(PostponeElement, Element); +PLUMA_INHERIT_PROVIDER(PostponeElement, ExecutableContentImpl); #endif } diff --git a/src/uscxml/plugins/element/response/ResponseElement.cpp b/src/uscxml/plugins/element/response/ResponseElement.cpp index 2da0d07..cd7ef2d 100644 --- a/src/uscxml/plugins/element/response/ResponseElement.cpp +++ b/src/uscxml/plugins/element/response/ResponseElement.cpp @@ -35,7 +35,7 @@ void ResponseElement::enterElement(const Arabica::DOM::Node& node) std::string requestId = (HAS_ATTR(node, "request") ? ATTR(node, "request") : _interpreter->getDataModel().evalAsString(ATTR(node, "requestexpr"))); // try to get the request object - HTTPServletInvoker* servlet = _interpreter->getHTTPServlet(); + InterpreterServlet* servlet = _interpreter->getHTTPServlet(); tthread::lock_guard lock(servlet->getMutex()); if (servlet->getRequests().find(requestId) == servlet->getRequests().end()) { diff --git a/src/uscxml/plugins/element/response/ResponseElement.h b/src/uscxml/plugins/element/response/ResponseElement.h index 9b3ce61..de3991c 100644 --- a/src/uscxml/plugins/element/response/ResponseElement.h +++ b/src/uscxml/plugins/element/response/ResponseElement.h @@ -33,7 +33,7 @@ public: }; #ifdef BUILD_AS_PLUGINS -PLUMA_INHERIT_PROVIDER(ResponseElement, Element); +PLUMA_INHERIT_PROVIDER(ResponseElement, ExecutableContentImpl); #endif } diff --git a/src/uscxml/plugins/invoker/ffmpeg/FFMPEGInvoker.h b/src/uscxml/plugins/invoker/ffmpeg/FFMPEGInvoker.h index 9b1b0ca..734467f 100644 --- a/src/uscxml/plugins/invoker/ffmpeg/FFMPEGInvoker.h +++ b/src/uscxml/plugins/invoker/ffmpeg/FFMPEGInvoker.h @@ -31,7 +31,7 @@ protected: }; #ifdef BUILD_AS_PLUGINS -PLUMA_INHERIT_PROVIDER(FFMPEGInvoker, Invoker); +PLUMA_INHERIT_PROVIDER(FFMPEGInvoker, InvokerImpl); #endif } diff --git a/src/uscxml/plugins/invoker/filesystem/dirmon/DirMonInvoker.h b/src/uscxml/plugins/invoker/filesystem/dirmon/DirMonInvoker.h index 3fd9258..e2abf54 100644 --- a/src/uscxml/plugins/invoker/filesystem/dirmon/DirMonInvoker.h +++ b/src/uscxml/plugins/invoker/filesystem/dirmon/DirMonInvoker.h @@ -91,7 +91,7 @@ protected: }; #ifdef BUILD_AS_PLUGINS -PLUMA_INHERIT_PROVIDER(DirMonInvoker, Invoker); +PLUMA_INHERIT_PROVIDER(DirMonInvoker, InvokerImpl); #endif } diff --git a/src/uscxml/plugins/invoker/filesystem/dirmon/FileWatcher/FileWatcher.cpp b/src/uscxml/plugins/invoker/filesystem/dirmon/FileWatcher/FileWatcher.cpp deleted file mode 100644 index 9399495..0000000 --- a/src/uscxml/plugins/invoker/filesystem/dirmon/FileWatcher/FileWatcher.cpp +++ /dev/null @@ -1,75 +0,0 @@ -/** - Copyright (c) 2009 James Wynn (james@jameswynn.com) - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - THE SOFTWARE. -*/ - -#include -#include - -#if FILEWATCHER_PLATFORM == FILEWATCHER_PLATFORM_WIN32 -# include -# define FILEWATCHER_IMPL FileWatcherWin32 -#elif FILEWATCHER_PLATFORM == FILEWATCHER_PLATFORM_KQUEUE -# include -# define FILEWATCHER_IMPL FileWatcherOSX -#elif FILEWATCHER_PLATFORM == FILEWATCHER_PLATFORM_LINUX -# include -# define FILEWATCHER_IMPL FileWatcherLinux -#endif - -namespace FW { - -//-------- -FileWatcher::FileWatcher() { - mImpl = new FILEWATCHER_IMPL(); -} - -//-------- -FileWatcher::~FileWatcher() { - delete mImpl; - mImpl = 0; -} - -//-------- -WatchID FileWatcher::addWatch(const String& directory, FileWatchListener* watcher) { - return mImpl->addWatch(directory, watcher, false); -} - -//-------- -WatchID FileWatcher::addWatch(const String& directory, FileWatchListener* watcher, bool recursive) { - return mImpl->addWatch(directory, watcher, recursive); -} - -//-------- -void FileWatcher::removeWatch(const String& directory) { - mImpl->removeWatch(directory); -} - -//-------- -void FileWatcher::removeWatch(WatchID watchid) { - mImpl->removeWatch(watchid); -} - -//-------- -void FileWatcher::update() { - mImpl->update(); -} - -};//namespace FW diff --git a/src/uscxml/plugins/invoker/filesystem/dirmon/FileWatcher/FileWatcher.h b/src/uscxml/plugins/invoker/filesystem/dirmon/FileWatcher/FileWatcher.h deleted file mode 100644 index 0e659b6..0000000 --- a/src/uscxml/plugins/invoker/filesystem/dirmon/FileWatcher/FileWatcher.h +++ /dev/null @@ -1,141 +0,0 @@ -/** - Main header for the FileWatcher class. Declares all implementation - classes to reduce compilation overhead. - - @author James Wynn - @date 4/15/2009 - - Copyright (c) 2009 James Wynn (james@jameswynn.com) - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - THE SOFTWARE. -*/ - -#ifndef _FW_FILEWATCHER_H_ -#define _FW_FILEWATCHER_H_ -#pragma once - -#include -#include - -namespace FW { -/// Type for a string -typedef std::string String; -/// Type for a watch id -typedef unsigned long WatchID; - -// forward declarations -class FileWatcherImpl; -class FileWatchListener; - -/// Base exception class -/// @class Exception -class Exception : public std::runtime_error { -public: - Exception(const String& message) - : std::runtime_error(message) - {} -}; - -/// Exception thrown when a file is not found. -/// @class FileNotFoundException -class FileNotFoundException : public Exception { -public: - FileNotFoundException() - : Exception("File not found") - {} - - FileNotFoundException(const String& filename) - : Exception("File not found (" + filename + ")") - {} -}; - -/// Actions to listen for. Rename will send two events, one for -/// the deletion of the old file, and one for the creation of the -/// new file. -namespace Actions { -enum Action { - /// Sent when a file is created or renamed - Add = 1, - /// Sent when a file is deleted or renamed - Delete = 2, - /// Sent when a file is modified - Modified = 4, - /// Sent when an existing file is reported - Existing = 8 -}; -}; -typedef Actions::Action Action; - -/// Listens to files and directories and dispatches events -/// to notify the parent program of the changes. -/// @class FileWatcher -class FileWatcher { -public: - /// - /// - FileWatcher(); - - /// - /// - virtual ~FileWatcher(); - - /// Add a directory watch. Same as the other addWatch, but doesn't have recursive option. - /// For backwards compatibility. - /// @exception FileNotFoundException Thrown when the requested directory does not exist - WatchID addWatch(const String& directory, FileWatchListener* watcher); - - /// Add a directory watch - /// @exception FileNotFoundException Thrown when the requested directory does not exist - WatchID addWatch(const String& directory, FileWatchListener* watcher, bool recursive); - - /// Remove a directory watch. This is a brute force search O(nlogn). - void removeWatch(const String& directory); - - /// Remove a directory watch. This is a map lookup O(logn). - void removeWatch(WatchID watchid); - - /// Updates the watcher. Must be called often. - void update(); - -private: - /// The implementation - FileWatcherImpl* mImpl; - -};//end FileWatcher - - -/// Basic interface for listening for file events. -/// @class FileWatchListener -class FileWatchListener { -public: - FileWatchListener() {} - virtual ~FileWatchListener() {} - - /// Handles the action file action - /// @param watchid The watch id for the directory - /// @param dir The directory - /// @param filename The filename that was accessed (not full path) - /// @param action Action that was performed - virtual void handleFileAction(WatchID watchid, const String& dir, const String& filename, Action action) = 0; - -};//class FileWatchListener - -};//namespace FW - -#endif//_FW_FILEWATCHER_H_ diff --git a/src/uscxml/plugins/invoker/filesystem/dirmon/FileWatcher/FileWatcherImpl.h b/src/uscxml/plugins/invoker/filesystem/dirmon/FileWatcher/FileWatcherImpl.h deleted file mode 100644 index 08cfed1..0000000 --- a/src/uscxml/plugins/invoker/filesystem/dirmon/FileWatcher/FileWatcherImpl.h +++ /dev/null @@ -1,77 +0,0 @@ -/** - Basic interface for the FileWatcher backend. - - @author James Wynn - @date 5/11/2009 - - Copyright (c) 2009 James Wynn (james@jameswynn.com) - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - THE SOFTWARE. -*/ -#ifndef _FW_FILEWATCHERIMPL_H_ -#define _FW_FILEWATCHERIMPL_H_ -#pragma once - -#include "FileWatcher.h" - -#define FILEWATCHER_PLATFORM_WIN32 1 -#define FILEWATCHER_PLATFORM_LINUX 2 -#define FILEWATCHER_PLATFORM_KQUEUE 3 - -#if defined(_WIN32) -# define FILEWATCHER_PLATFORM FILEWATCHER_PLATFORM_WIN32 -#elif defined(__APPLE_CC__) || defined(BSD) -# define FILEWATCHER_PLATFORM FILEWATCHER_PLATFORM_KQUEUE -#elif defined(__linux__) -# define FILEWATCHER_PLATFORM FILEWATCHER_PLATFORM_LINUX -#endif - -namespace FW { -struct WatchStruct; - -class FileWatcherImpl { -public: - /// - /// - FileWatcherImpl() {} - - /// - /// - virtual ~FileWatcherImpl() {} - - /// Add a directory watch - /// @exception FileNotFoundException Thrown when the requested directory does not exist - virtual WatchID addWatch(const String& directory, FileWatchListener* watcher, bool recursive) = 0; - - /// Remove a directory watch. This is a brute force lazy search O(nlogn). - virtual void removeWatch(const String& directory) = 0; - - /// Remove a directory watch. This is a map lookup O(logn). - virtual void removeWatch(WatchID watchid) = 0; - - /// Updates the watcher. Must be called often. - virtual void update() = 0; - - /// Handles the action - virtual void handleAction(WatchStruct* watch, const String& filename, unsigned long action) = 0; - -};//end FileWatcherImpl -};//namespace FW - -#endif//_FW_FILEWATCHERIMPL_H_ diff --git a/src/uscxml/plugins/invoker/filesystem/dirmon/FileWatcher/FileWatcherLinux.cpp b/src/uscxml/plugins/invoker/filesystem/dirmon/FileWatcher/FileWatcherLinux.cpp deleted file mode 100644 index ea5d259..0000000 --- a/src/uscxml/plugins/invoker/filesystem/dirmon/FileWatcher/FileWatcherLinux.cpp +++ /dev/null @@ -1,166 +0,0 @@ -/** - Copyright (c) 2009 James Wynn (james@jameswynn.com) - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - THE SOFTWARE. - - James Wynn james@jameswynn.com -*/ - -#include - -#if FILEWATCHER_PLATFORM == FILEWATCHER_PLATFORM_LINUX - -#include -#include -#include -#include -#include -#include -#include - -#define BUFF_SIZE ((sizeof(struct inotify_event)+FILENAME_MAX)*1024) - -namespace FW { - -struct WatchStruct { - WatchID mWatchID; - String mDirName; - FileWatchListener* mListener; -}; - -//-------- -FileWatcherLinux::FileWatcherLinux() { - mFD = inotify_init(); - if (mFD < 0) - fprintf (stderr, "Error: %s\n", strerror(errno)); - - mTimeOut.tv_sec = 0; - mTimeOut.tv_usec = 0; - - FD_ZERO(&mDescriptorSet); -} - -//-------- -FileWatcherLinux::~FileWatcherLinux() { - WatchMap::iterator iter = mWatches.begin(); - WatchMap::iterator end = mWatches.end(); - for(; iter != end; ++iter) { - delete iter->second; - } - mWatches.clear(); -} - -//-------- -WatchID FileWatcherLinux::addWatch(const String& directory, FileWatchListener* watcher, bool recursive) { - int wd = inotify_add_watch (mFD, directory.c_str(), - IN_CLOSE_WRITE | IN_MOVED_TO | IN_CREATE | IN_MOVED_FROM | IN_DELETE); - if (wd < 0) { - if(errno == ENOENT) - throw FileNotFoundException(directory); - else - throw Exception(strerror(errno)); - -// fprintf (stderr, "Error: %s\n", strerror(errno)); -// return -1; - } - - WatchStruct* pWatch = new WatchStruct(); - pWatch->mListener = watcher; - pWatch->mWatchID = wd; - pWatch->mDirName = directory; - - mWatches.insert(std::make_pair(wd, pWatch)); - - return wd; -} - -//-------- -void FileWatcherLinux::removeWatch(const String& directory) { - WatchMap::iterator iter = mWatches.begin(); - WatchMap::iterator end = mWatches.end(); - for(; iter != end; ++iter) { - if(directory == iter->second->mDirName) { - removeWatch(iter->first); - return; - } - } -} - -//-------- -void FileWatcherLinux::removeWatch(WatchID watchid) { - WatchMap::iterator iter = mWatches.find(watchid); - - if(iter == mWatches.end()) - return; - - WatchStruct* watch = iter->second; - mWatches.erase(iter); - - inotify_rm_watch(mFD, watchid); - - delete watch; - watch = 0; -} - -//-------- -void FileWatcherLinux::update() { - FD_SET(mFD, &mDescriptorSet); - - int ret = select(mFD + 1, &mDescriptorSet, NULL, NULL, &mTimeOut); - if(ret < 0) { - perror("select"); - } else if(FD_ISSET(mFD, &mDescriptorSet)) { - ssize_t len, i = 0; - char action[81+FILENAME_MAX] = {0}; - char buff[BUFF_SIZE] = {0}; - - len = read (mFD, buff, BUFF_SIZE); - - while (i < len) { - struct inotify_event *pevent = (struct inotify_event *)&buff[i]; - - WatchStruct* watch = mWatches[pevent->wd]; - handleAction(watch, pevent->name, pevent->mask); - i += sizeof(struct inotify_event) + pevent->len; - } - } -} - -//-------- -void FileWatcherLinux::handleAction(WatchStruct* watch, const String& filename, unsigned long action) { - if(!watch->mListener) - return; - - if(IN_CLOSE_WRITE & action) { - watch->mListener->handleFileAction(watch->mWatchID, watch->mDirName, filename, - Actions::Modified); - } - if(IN_MOVED_TO & action || IN_CREATE & action) { - watch->mListener->handleFileAction(watch->mWatchID, watch->mDirName, filename, - Actions::Add); - } - if(IN_MOVED_FROM & action || IN_DELETE & action) { - watch->mListener->handleFileAction(watch->mWatchID, watch->mDirName, filename, - Actions::Delete); - } -} - -};//namespace FW - -#endif//FILEWATCHER_PLATFORM_LINUX diff --git a/src/uscxml/plugins/invoker/filesystem/dirmon/FileWatcher/FileWatcherLinux.h b/src/uscxml/plugins/invoker/filesystem/dirmon/FileWatcher/FileWatcherLinux.h deleted file mode 100644 index b681e52..0000000 --- a/src/uscxml/plugins/invoker/filesystem/dirmon/FileWatcher/FileWatcherLinux.h +++ /dev/null @@ -1,89 +0,0 @@ -/** - Implementation header file for Linux based on inotify. - - @author James Wynn - @date 4/15/2009 - - Copyright (c) 2009 James Wynn (james@jameswynn.com) - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - THE SOFTWARE. -*/ -#ifndef _FW_FILEWATCHERLINUX_H_ -#define _FW_FILEWATCHERLINUX_H_ -#pragma once - -#include "FileWatcherImpl.h" - -#if FILEWATCHER_PLATFORM == FILEWATCHER_PLATFORM_LINUX - -#include -#include - -namespace FW { -/// Implementation for Linux based on inotify. -/// @class FileWatcherLinux -class FileWatcherLinux : public FileWatcherImpl { -public: - /// type for a map from WatchID to WatchStruct pointer - typedef std::map WatchMap; - -public: - /// - /// - FileWatcherLinux(); - - /// - /// - virtual ~FileWatcherLinux(); - - /// Add a directory watch - /// @exception FileNotFoundException Thrown when the requested directory does not exist - WatchID addWatch(const String& directory, FileWatchListener* watcher, bool recursive); - - /// Remove a directory watch. This is a brute force lazy search O(nlogn). - void removeWatch(const String& directory); - - /// Remove a directory watch. This is a map lookup O(logn). - void removeWatch(WatchID watchid); - - /// Updates the watcher. Must be called often. - void update(); - - /// Handles the action - void handleAction(WatchStruct* watch, const String& filename, unsigned long action); - -private: - /// Map of WatchID to WatchStruct pointers - WatchMap mWatches; - /// The last watchid - WatchID mLastWatchID; - /// inotify file descriptor - int mFD; - /// time out data - struct timeval mTimeOut; - /// File descriptor set - fd_set mDescriptorSet; - -};//end FileWatcherLinux - -};//namespace FW - -#endif//FILEWATCHER_PLATFORM_LINUX - -#endif//_FW_FILEWATCHERLINUX_H_ diff --git a/src/uscxml/plugins/invoker/filesystem/dirmon/FileWatcher/FileWatcherOSX.cpp b/src/uscxml/plugins/invoker/filesystem/dirmon/FileWatcher/FileWatcherOSX.cpp deleted file mode 100644 index a47d635..0000000 --- a/src/uscxml/plugins/invoker/filesystem/dirmon/FileWatcher/FileWatcherOSX.cpp +++ /dev/null @@ -1,386 +0,0 @@ -/** - Copyright (c) 2009 James Wynn (james@jameswynn.com) - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - THE SOFTWARE. - - James Wynn james@jameswynn.com -*/ - -#include - -#if FILEWATCHER_PLATFORM == FILEWATCHER_PLATFORM_KQUEUE - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -// this is more suited: -// https://developer.apple.com/library/mac/#documentation/Darwin/Conceptual/FSEvents_ProgGuide/UsingtheFSEventsFramework/UsingtheFSEventsFramework.html - -namespace FW { - -#define MAX_CHANGE_EVENT_SIZE 2000 - -typedef struct kevent KEvent; - -struct EntryStruct { - EntryStruct(const char* filename, time_t mtime = 0) - : mFilename(filename), mModifiedTime(mtime) { - } - ~EntryStruct() { - delete[] mFilename; - } - const char* mFilename; - time_t mModifiedTime; -}; - -int comparator(const void* ke1, const void* ke2) { - /*KEvent* kevent1 = (KEvent*) ke1; - KEvent* kevent2 = (KEvent*) ke2; - - EntryStruct* event1 = (EntryStruct*)kevent1->udata; - EntryStruct* event2 = (EntryStruct*)kevent2->udata; - return strcmp(event1->mFilename, event2->mFilename); - */ - return strcmp(((EntryStruct*)(((KEvent*)(ke1))->udata))->mFilename, ((EntryStruct*)(((KEvent*)(ke2))->udata))->mFilename); -} - -struct WatchStruct { - WatchID mWatchID; - String mDirName; - FileWatchListener* mListener; - FileWatcherOSX* mWatcher; - bool mRecursive; - - // index 0 is always the directory - KEvent mChangeList[MAX_CHANGE_EVENT_SIZE]; - size_t mChangeListCount; - - WatchStruct(WatchID watchid, const String& dirname, FileWatchListener* listener, FileWatcherOSX* watcher, bool recursive = false) - : mWatchID(watchid), mDirName(dirname), mListener(listener), mWatcher(watcher), mRecursive(recursive) { - mChangeListCount = 0; - addAll(); - } - - void addFile(const String& name, bool emitEvents = true) { - //fprintf(stderr, "ADDED: %s\n", name.c_str()); - - // create entry - struct stat attrib; - stat(name.c_str(), &attrib); - - int fd = open(name.c_str(), O_RDONLY); - - if(fd == -1) - throw FileNotFoundException(name); - - ++mChangeListCount; - - char* namecopy = new char[name.length() + 1]; - strncpy(namecopy, name.c_str(), name.length()); - namecopy[name.length()] = 0; - EntryStruct* entry = new EntryStruct(namecopy, attrib.st_mtime); - - // set the event data at the end of the list - EV_SET(&mChangeList[mChangeListCount], fd, EVFILT_VNODE, - EV_ADD | EV_ENABLE | EV_ONESHOT, - NOTE_DELETE | NOTE_EXTEND | NOTE_WRITE | NOTE_ATTRIB | NOTE_RENAME, - 0, (void*)entry); - - // qsort - qsort(mChangeList + 1, mChangeListCount, sizeof(KEvent), comparator); - - // handle action - if(emitEvents) - handleAction(name, Actions::Add); - } - - void removeFile(const String& name, bool emitEvents = true) { - // bsearch - KEvent target; - EntryStruct tempEntry(name.c_str(), 0); - target.udata = &tempEntry; - KEvent* ke = (KEvent*)bsearch(&target, &mChangeList, mChangeListCount + 1, sizeof(KEvent), comparator); - if(!ke) - throw FileNotFoundException(name); - - tempEntry.mFilename = 0; - - // delete - close(ke->ident); - delete((EntryStruct*)ke->udata); - memset(ke, 0, sizeof(KEvent)); - - // move end to current - memcpy(ke, &mChangeList[mChangeListCount], sizeof(KEvent)); - memset(&mChangeList[mChangeListCount], 0, sizeof(KEvent)); - --mChangeListCount; - - // qsort - qsort(mChangeList + 1, mChangeListCount, sizeof(KEvent), comparator); - - // handle action - if(emitEvents) - handleAction(name, Actions::Delete); - } - - // called when the directory is actually changed - // means a file has been added or removed - // rescans the watched directory adding/removing files and sending notices - void rescan() { - // if new file, call addFile - // if missing file, call removeFile - // if timestamp modified, call handleAction(filename, ACTION_MODIFIED); - DIR* dir = opendir(mDirName.c_str()); - if(!dir) - return; - - struct dirent* dentry; - KEvent* ke = &mChangeList[1]; - EntryStruct* entry = 0; - struct stat attrib; - - while((dentry = readdir(dir)) != NULL) { - String fname = mDirName + "/" + dentry->d_name; - stat(fname.c_str(), &attrib); - if(!S_ISREG(attrib.st_mode)) - continue; - - if(ke <= &mChangeList[mChangeListCount]) { - entry = (EntryStruct*)ke->udata; - int result = strcmp(entry->mFilename, fname.c_str()); - //fprintf(stderr, "[%s cmp %s]\n", entry->mFilename, fname.c_str()); - if(result == 0) { - stat(entry->mFilename, &attrib); - time_t timestamp = attrib.st_mtime; - - if(entry->mModifiedTime != timestamp) { - entry->mModifiedTime = timestamp; - handleAction(entry->mFilename, Actions::Modified); - } - ke++; - } else if(result < 0) { - // f1 was deleted - removeFile(entry->mFilename); - ke++; - } else { - // f2 was created - addFile(fname); - ke++; - } - } else { - // just add - addFile(fname); - ke++; - } - }//end while - - closedir(dir); - }; - - void handleAction(const String& filename, FW::Action action) { - mListener->handleFileAction(mWatchID, mDirName, filename, action); - } - - void addAll() { - // add base dir - int fd = open(mDirName.c_str(), O_RDONLY); - EV_SET(&mChangeList[0], fd, EVFILT_VNODE, - EV_ADD | EV_ENABLE | EV_ONESHOT, - NOTE_DELETE | NOTE_EXTEND | NOTE_WRITE | NOTE_ATTRIB | NOTE_RENAME, - 0, 0); - - //fprintf(stderr, "ADDED: %s\n", mDirName.c_str()); - - // scan directory and call addFile(name, false) on each file - DIR* dir = opendir(mDirName.c_str()); - if(!dir) - throw FileNotFoundException(mDirName); - - struct dirent* entry; - struct stat attrib; - while((entry = readdir(dir)) != NULL) { - String fname = (mDirName + "/" + String(entry->d_name)); - stat(fname.c_str(), &attrib); - if(S_ISREG(attrib.st_mode)) { - addFile(fname, false); - } else if(S_IFDIR && mRecursive && entry->d_name[0] != '.') { - mWatcher->addWatch(fname, mListener, mRecursive); - } else { - fprintf(stderr, "NOT ADDED: %s (%d)\n", fname.c_str(), attrib.st_mode); - } - }//end while - - closedir(dir); - } - - void removeAll() { - KEvent* ke = NULL; - - // go through list removing each file and sending an event - for(int i = 0; i < mChangeListCount; ++i) { - ke = &mChangeList[i]; - //handleAction(name, Action::Delete); - EntryStruct* entry = (EntryStruct*)ke->udata; - - handleAction(entry->mFilename, Actions::Delete); - - // delete - close(ke->ident); - delete((EntryStruct*)ke->udata); - } - } -}; - -void FileWatcherOSX::update() { - int nev = 0; - struct kevent event; - - WatchMap::iterator iter = mWatches.begin(); - WatchMap::iterator end = mWatches.end(); - for(; iter != end; ++iter) { - WatchStruct* watch = iter->second; - - while((nev = kevent(mDescriptor, (KEvent*)&(watch->mChangeList), watch->mChangeListCount + 1, &event, 1, &mTimeOut)) != 0) { - if(nev == -1) - perror("kevent"); - else { - if (event.fflags & NOTE_DELETE) { - fprintf(stderr, "NOTE_DELETE "); - } - if (event.fflags & NOTE_EXTEND) { - fprintf(stderr, "NOTE_EXTEND "); - } - if (event.fflags & NOTE_WRITE) { - fprintf(stderr, "NOTE_WRITE "); - } - if (event.fflags & NOTE_ATTRIB) { - fprintf(stderr, "NOTE_ATTRIB "); - } - if (event.fflags & NOTE_RENAME) { - fprintf(stderr, "NOTE_RENAME "); - } - - EntryStruct* entry = 0; - if((entry = (EntryStruct*)event.udata) != 0) { - fprintf(stderr, " to %s -- \n", (char*)entry->mFilename); - - if(event.fflags & NOTE_DELETE) { - //watch->handleAction(entry->mFilename, Action::Delete); - watch->removeFile(entry->mFilename); - } - if(event.fflags & NOTE_EXTEND || - event.fflags & NOTE_WRITE || - event.fflags & NOTE_ATTRIB) { - //watch->rescan(); - struct stat attrib; - stat(entry->mFilename, &attrib); - entry->mModifiedTime = attrib.st_mtime; - watch->handleAction(entry->mFilename, FW::Actions::Modified); - } - } else { - fprintf(stderr, " in %s -- rescanning\n", watch->mDirName.c_str()); - watch->rescan(); - } - } - } - } -} - -//-------- -FileWatcherOSX::FileWatcherOSX() { - mDescriptor = kqueue(); - mTimeOut.tv_sec = 0; - mTimeOut.tv_nsec = 20000000; -} - -//-------- -FileWatcherOSX::~FileWatcherOSX() { - WatchMap::iterator iter = mWatches.begin(); - WatchMap::iterator end = mWatches.end(); - for(; iter != end; ++iter) { - delete iter->second; - } - mWatches.clear(); - - close(mDescriptor); -} - -//-------- -WatchID FileWatcherOSX::addWatch(const String& directory, FileWatchListener* watcher, bool recursive) { - /* int fd = open(directory.c_str(), O_RDONLY); - if(fd == -1) - perror("open"); - - EV_SET(&change, fd, EVFILT_VNODE, - EV_ADD | EV_ENABLE | EV_ONESHOT, - NOTE_DELETE | NOTE_EXTEND | NOTE_WRITE | NOTE_ATTRIB, - 0, (void*)"testing"); - */ - - std::cout << "Adding watch for " << directory << std::endl; - - WatchID currWatch = ++mLastWatchID; - WatchStruct* watch = new WatchStruct(currWatch, directory, watcher, this, recursive); - mWatches.insert(std::make_pair(currWatch, watch)); - return currWatch; -} - -//-------- -void FileWatcherOSX::removeWatch(const String& directory) { - WatchMap::iterator iter = mWatches.begin(); - WatchMap::iterator end = mWatches.end(); - for(; iter != end; ++iter) { - if(directory == iter->second->mDirName) { - removeWatch(iter->first); - return; - } - } -} - -//-------- -void FileWatcherOSX::removeWatch(WatchID watchid) { - WatchMap::iterator iter = mWatches.find(watchid); - - if(iter == mWatches.end()) - return; - - WatchStruct* watch = iter->second; - mWatches.erase(iter); - - //inotify_rm_watch(mFD, watchid); - - delete watch; - watch = 0; -} - -//-------- -void FileWatcherOSX::handleAction(WatchStruct* watch, const String& filename, unsigned long action) { -} - -};//namespace FW - -#endif//FILEWATCHER_PLATFORM_KQUEUE diff --git a/src/uscxml/plugins/invoker/filesystem/dirmon/FileWatcher/FileWatcherOSX.h b/src/uscxml/plugins/invoker/filesystem/dirmon/FileWatcher/FileWatcherOSX.h deleted file mode 100644 index 92e3957..0000000 --- a/src/uscxml/plugins/invoker/filesystem/dirmon/FileWatcher/FileWatcherOSX.h +++ /dev/null @@ -1,88 +0,0 @@ -/** - Implementation header file for OSX based on KEvent. - - @author James Wynn - @date 4/15/2009 - - Copyright (c) 2009 James Wynn (james@jameswynn.com) - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - THE SOFTWARE. -*/ -#ifndef _FW_FILEWATCHEROSX_H_ -#define _FW_FILEWATCHEROSX_H_ -#pragma once - -#include "FileWatcherImpl.h" - -#if FILEWATCHER_PLATFORM == FILEWATCHER_PLATFORM_KQUEUE - -#include -#include - -namespace FW { -/// Implementation for OSX based on kqueue. -/// @class FileWatcherOSX -class FileWatcherOSX : public FileWatcherImpl { -public: - /// type for a map from WatchID to WatchStruct pointer - typedef std::map WatchMap; - -public: - /// - /// - FileWatcherOSX(); - - /// - /// - virtual ~FileWatcherOSX(); - - /// Add a directory watch - /// @exception FileNotFoundException Thrown when the requested directory does not exist - WatchID addWatch(const String& directory, FileWatchListener* watcher, bool recursive = false); - - /// Remove a directory watch. This is a brute force lazy search O(nlogn). - void removeWatch(const String& directory); - - /// Remove a directory watch. This is a map lookup O(logn). - void removeWatch(WatchID watchid); - - /// Updates the watcher. Must be called often. - void update(); - - /// Handles the action - void handleAction(WatchStruct* watch, const String& filename, unsigned long action); - -private: - /// Map of WatchID to WatchStruct pointers - WatchMap mWatches; - /// The descriptor for the kqueue - int mDescriptor; - /// time out data - struct timespec mTimeOut; - /// WatchID allocator - int mLastWatchID; - - friend class WatchStruct; -};//end FileWatcherOSX - -};//namespace FW - -#endif//__APPLE_CC__ - -#endif//_FW_FILEWATCHEROSX_H_ diff --git a/src/uscxml/plugins/invoker/filesystem/dirmon/FileWatcher/FileWatcherWin32.cpp b/src/uscxml/plugins/invoker/filesystem/dirmon/FileWatcher/FileWatcherWin32.cpp deleted file mode 100644 index ee5de7e..0000000 --- a/src/uscxml/plugins/invoker/filesystem/dirmon/FileWatcher/FileWatcherWin32.cpp +++ /dev/null @@ -1,244 +0,0 @@ -/** - Copyright (c) 2009 James Wynn (james@jameswynn.com) - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - THE SOFTWARE. -*/ - -#include - -#if FILEWATCHER_PLATFORM == FILEWATCHER_PLATFORM_WIN32 - -#define _WIN32_WINNT 0x0550 -#include - -#if defined(_MSC_VER) -#pragma comment(lib, "comctl32.lib") -#pragma comment(lib, "user32.lib") -#pragma comment(lib, "ole32.lib") - -// disable secure warnings -#pragma warning (disable: 4996) -#endif - -namespace FW { -/// Internal watch data -struct WatchStruct { - OVERLAPPED mOverlapped; - HANDLE mDirHandle; - BYTE mBuffer[32 * 1024]; - LPARAM lParam; - DWORD mNotifyFilter; - bool mStopNow; - FileWatcherImpl* mFileWatcher; - FileWatchListener* mFileWatchListener; - char* mDirName; - WatchID mWatchid; - bool mIsRecursive; -}; - -#pragma region Internal Functions - -// forward decl -bool RefreshWatch(WatchStruct* pWatch, bool _clear = false); - -/// Unpacks events and passes them to a user defined callback. -void CALLBACK WatchCallback(DWORD dwErrorCode, DWORD dwNumberOfBytesTransfered, LPOVERLAPPED lpOverlapped) { - TCHAR szFile[MAX_PATH]; - PFILE_NOTIFY_INFORMATION pNotify; - WatchStruct* pWatch = (WatchStruct*) lpOverlapped; - size_t offset = 0; - - if(dwNumberOfBytesTransfered == 0) - return; - - if (dwErrorCode == ERROR_SUCCESS) { - do { - pNotify = (PFILE_NOTIFY_INFORMATION) &pWatch->mBuffer[offset]; - offset += pNotify->NextEntryOffset; - -# if defined(UNICODE) - { - lstrcpynW(szFile, pNotify->FileName, - min(MAX_PATH, pNotify->FileNameLength / sizeof(WCHAR) + 1)); - } -# else - { - int count = WideCharToMultiByte(CP_ACP, 0, pNotify->FileName, - pNotify->FileNameLength / sizeof(WCHAR), - szFile, MAX_PATH - 1, NULL, NULL); - szFile[count] = TEXT('\0'); - } -# endif - - pWatch->mFileWatcher->handleAction(pWatch, szFile, pNotify->Action); - - } while (pNotify->NextEntryOffset != 0); - } - - if (!pWatch->mStopNow) { - RefreshWatch(pWatch); - } -} - -/// Refreshes the directory monitoring. -bool RefreshWatch(WatchStruct* pWatch, bool _clear) { - return ReadDirectoryChangesW( - pWatch->mDirHandle, pWatch->mBuffer, sizeof(pWatch->mBuffer), pWatch->mIsRecursive, - pWatch->mNotifyFilter, NULL, &pWatch->mOverlapped, _clear ? 0 : WatchCallback) != 0; -} - -/// Stops monitoring a directory. -void DestroyWatch(WatchStruct* pWatch) { - if (pWatch) { - pWatch->mStopNow = TRUE; - - CancelIo(pWatch->mDirHandle); - - RefreshWatch(pWatch, true); - - if (!HasOverlappedIoCompleted(&pWatch->mOverlapped)) { - SleepEx(5, TRUE); - } - - CloseHandle(pWatch->mOverlapped.hEvent); - CloseHandle(pWatch->mDirHandle); - delete pWatch->mDirName; - HeapFree(GetProcessHeap(), 0, pWatch); - } -} - -/// Starts monitoring a directory. -WatchStruct* CreateWatch(LPCTSTR szDirectory, bool recursive, DWORD mNotifyFilter) { - WatchStruct* pWatch; - size_t ptrsize = sizeof(*pWatch); - pWatch = static_cast(HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, ptrsize)); - - pWatch->mDirHandle = CreateFile(szDirectory, FILE_LIST_DIRECTORY, - FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, - OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OVERLAPPED, NULL); - - if (pWatch->mDirHandle != INVALID_HANDLE_VALUE) { - pWatch->mOverlapped.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); - pWatch->mNotifyFilter = mNotifyFilter; - pWatch->mIsRecursive = recursive; - - if (RefreshWatch(pWatch)) { - return pWatch; - } else { - CloseHandle(pWatch->mOverlapped.hEvent); - CloseHandle(pWatch->mDirHandle); - } - } - - HeapFree(GetProcessHeap(), 0, pWatch); - return NULL; -} - -#pragma endregion - -//-------- -FileWatcherWin32::FileWatcherWin32() - : mLastWatchID(0) { -} - -//-------- -FileWatcherWin32::~FileWatcherWin32() { - WatchMap::iterator iter = mWatches.begin(); - WatchMap::iterator end = mWatches.end(); - for(; iter != end; ++iter) { - DestroyWatch(iter->second); - } - mWatches.clear(); -} - -//-------- -WatchID FileWatcherWin32::addWatch(const String& directory, FileWatchListener* watcher, bool recursive) { - WatchID watchid = ++mLastWatchID; - - WatchStruct* watch = CreateWatch(directory.c_str(), recursive, - FILE_NOTIFY_CHANGE_CREATION | FILE_NOTIFY_CHANGE_SIZE | FILE_NOTIFY_CHANGE_FILE_NAME); - - if(!watch) - throw FileNotFoundException(directory); - - watch->mWatchid = watchid; - watch->mFileWatcher = this; - watch->mFileWatchListener = watcher; - watch->mDirName = new char[directory.length()+1]; - strcpy(watch->mDirName, directory.c_str()); - - mWatches.insert(std::make_pair(watchid, watch)); - - return watchid; -} - -//-------- -void FileWatcherWin32::removeWatch(const String& directory) { - WatchMap::iterator iter = mWatches.begin(); - WatchMap::iterator end = mWatches.end(); - for(; iter != end; ++iter) { - if(directory == iter->second->mDirName) { - removeWatch(iter->first); - return; - } - } -} - -//-------- -void FileWatcherWin32::removeWatch(WatchID watchid) { - WatchMap::iterator iter = mWatches.find(watchid); - - if(iter == mWatches.end()) - return; - - WatchStruct* watch = iter->second; - mWatches.erase(iter); - - DestroyWatch(watch); -} - -//-------- -void FileWatcherWin32::update() { - MsgWaitForMultipleObjectsEx(0, NULL, 0, QS_ALLINPUT, MWMO_ALERTABLE); -} - -//-------- -void FileWatcherWin32::handleAction(WatchStruct* watch, const String& filename, unsigned long action) { - Action fwAction; - - switch(action) { - case FILE_ACTION_RENAMED_NEW_NAME: - case FILE_ACTION_ADDED: - fwAction = Actions::Add; - break; - case FILE_ACTION_RENAMED_OLD_NAME: - case FILE_ACTION_REMOVED: - fwAction = Actions::Delete; - break; - case FILE_ACTION_MODIFIED: - fwAction = Actions::Modified; - break; - }; - - watch->mFileWatchListener->handleFileAction(watch->mWatchid, watch->mDirName, filename, fwAction); -} - -};//namespace FW - -#endif//_WIN32 diff --git a/src/uscxml/plugins/invoker/filesystem/dirmon/FileWatcher/FileWatcherWin32.h b/src/uscxml/plugins/invoker/filesystem/dirmon/FileWatcher/FileWatcherWin32.h deleted file mode 100644 index d1626b0..0000000 --- a/src/uscxml/plugins/invoker/filesystem/dirmon/FileWatcher/FileWatcherWin32.h +++ /dev/null @@ -1,83 +0,0 @@ -/** - Implementation for Windows. Uses ReadDirectoryChangesW to watch for - file system changes. - - @author James Wynn - @date 4/15/2009 - - Copyright (c) 2009 James Wynn (james@jameswynn.com) - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - THE SOFTWARE. -*/ -#ifndef _FW_FILEWATCHERWIN32_H_ -#define _FW_FILEWATCHERWIN32_H_ -#pragma once - -#include "FileWatcherImpl.h" - -#if FILEWATCHER_PLATFORM == FILEWATCHER_PLATFORM_WIN32 - -#include - -namespace FW { -/// Implementation for Win32 based on ReadDirectoryChangesW. -/// @class FileWatcherWin32 -class FileWatcherWin32 : public FileWatcherImpl { -public: - /// type for a map from WatchID to WatchStruct pointer - typedef std::map WatchMap; - -public: - /// - /// - FileWatcherWin32(); - - /// - /// - virtual ~FileWatcherWin32(); - - /// Add a directory watch - /// @exception FileNotFoundException Thrown when the requested directory does not exist - WatchID addWatch(const String& directory, FileWatchListener* watcher, bool recursive); - - /// Remove a directory watch. This is a brute force lazy search O(nlogn). - void removeWatch(const String& directory); - - /// Remove a directory watch. This is a map lookup O(logn). - void removeWatch(WatchID watchid); - - /// Updates the watcher. Must be called often. - void update(); - - /// Handles the action - void handleAction(WatchStruct* watch, const String& filename, unsigned long action); - -private: - /// Map of WatchID to WatchStruct pointers - WatchMap mWatches; - /// The last watchid - WatchID mLastWatchID; - -};//end FileWatcherWin32 - -};//namespace FW - -#endif//FILEWATCHER_PLATFORM_WIN32 - -#endif//_FW_FILEWATCHERWIN32_H_ diff --git a/src/uscxml/plugins/invoker/graphics/openscenegraph/OSGConverter.cpp b/src/uscxml/plugins/invoker/graphics/openscenegraph/OSGConverter.cpp deleted file mode 100644 index 93a238c..0000000 --- a/src/uscxml/plugins/invoker/graphics/openscenegraph/OSGConverter.cpp +++ /dev/null @@ -1,533 +0,0 @@ -#include "OSGConverter.h" -#include -#include "uscxml/config.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#ifdef BUILD_AS_PLUGINS -#include -#endif - -#define EVAL_PARAM_EXPR(param, expr, key) \ -if (param.find(key) == param.end() && param.find(expr) != param.end() && _interpreter->getDataModel()) \ - param.insert(std::make_pair(key, _interpreter->getDataModel().evalAsString(param.find(expr)->second))); - -#define CAST_PARAM(param, var, key, type) \ -if (param.find(key) != param.end()) { \ - try { var = boost::lexical_cast(param.find(key)->second); } \ - catch(...) { LOG(ERROR) << "Attribute " key " of sendrequest to osgconverter is of invalid format: " << param.find(key)->second; } \ -} - - -namespace uscxml { - -#ifdef BUILD_AS_PLUGINS -PLUMA_CONNECTOR -bool connect(pluma::Host& host) { - host.add( new OSGConverterProvider() ); - return true; -} -#endif - -OSGConverter::OSGConverter() : _isRunning(false) { -// osg::setNotifyLevel(osg::DEBUG_FP); -} - -OSGConverter::~OSGConverter() { - _isRunning = false; - std::set::iterator threadIter = _threads.begin(); - while(threadIter != _threads.end()) { - (*threadIter)->join(); - } -}; - -boost::shared_ptr OSGConverter::create(Interpreter* interpreter) { - boost::shared_ptr invoker = boost::shared_ptr(new OSGConverter()); - invoker->_interpreter = interpreter; - return invoker; -} - -Data OSGConverter::getDataModelVariables() { - Data data; - return data; -} - -void OSGConverter::send(const SendRequest& req) { - - /** - * we have to resolve all datamodel dependent strings first as - * we cannot access the datamodel from within another thread without locking - */ - - // make a copy - SendRequest actualReq(req); - - if (actualReq.params.find("source") == actualReq.params.end()) { - // no explicit source - if (actualReq.params.find("sourceexpr") != actualReq.params.end() && _interpreter->getDataModel()) { - actualReq.params.insert(std::make_pair("source", _interpreter->getDataModel().evalAsString(actualReq.params.find("sourceexpr")->second))); - } else { - LOG(ERROR) << "SendRequests for osginvoker missing source or sourceExpr and datamodel"; - return; - } - } - - if (actualReq.params.find("dest") == actualReq.params.end()) { - // no explicit destination - if (actualReq.params.find("destexpr") != actualReq.params.end() && _interpreter->getDataModel()) { - actualReq.params.insert(std::make_pair("dest", _interpreter->getDataModel().evalAsString(actualReq.params.find("destexpr")->second))); - } else { - LOG(ERROR) << "SendRequests for osginvoker missing dest or destExpr and datamodel"; - return; - } - } - - boost::algorithm::replace_all(actualReq.params.find("dest")->second, "//", "/"); - boost::algorithm::replace_all(actualReq.params.find("dest")->second, "\\\\", "\\"); - - if (actualReq.params.find("autorotate") == actualReq.params.end()) { - if (actualReq.params.find("autorotateexpr") != actualReq.params.end()) { - if (_interpreter->getDataModel()) { - actualReq.params.insert(std::make_pair("autorotate", _interpreter->getDataModel().evalAsString(actualReq.params.find("autorotateexpr")->second))); - } else { - LOG(ERROR) << "SendRequests for osginvoker ncludes autorotateexpr but no datamodel is specified"; - return; - } - } - } - - if (actualReq.params.find("format") == actualReq.params.end()) { - // no explicit format - if (actualReq.params.find("formatexpr") != actualReq.params.end() && _interpreter->getDataModel()) { - actualReq.params.insert(std::make_pair("format", _interpreter->getDataModel().evalAsString(actualReq.params.find("formatexpr")->second))); - } else { - std::string format; - size_t lastDot; - std::string dest = req.params.find("dest")->second; - if ((lastDot = dest.find_last_of(".")) != std::string::npos) { - lastDot++; - format = dest.substr(lastDot, dest.length() - lastDot); - } - if (format.length() == 0 || format.find_last_of(PATH_SEPERATOR) != std::string::npos) { - // empty format or pathseperator in format - format = "png"; - } - actualReq.params.insert(std::make_pair("format", format)); - } - } - -// assert(osgDB::Registry::instance()->getReaderWriterForExtension("png")); -// osgDB::Registry::ReaderWriterList formatList = osgDB::Registry::instance()->getReaderWriterList(); -// for (int i = 0; i < formatList.size(); i++) { -// std::map funcDesc = formatList[i]->supportedProtocols(); -// std::map::iterator funcDescIter = funcDesc.begin(); -// while(funcDescIter != funcDesc.end()) { -// std::cout << funcDescIter->first << ": " << funcDescIter->second << std::endl; -// funcDescIter++; -// } -// } - - EVAL_PARAM_EXPR(actualReq.params, "heightexpr", "height"); - EVAL_PARAM_EXPR(actualReq.params, "widthexpr", "width"); - EVAL_PARAM_EXPR(actualReq.params, "pitchexpr", "pitch"); - EVAL_PARAM_EXPR(actualReq.params, "rollexpr", "roll"); - EVAL_PARAM_EXPR(actualReq.params, "yawexpr", "yaw"); - EVAL_PARAM_EXPR(actualReq.params, "zoomexpr", "zoom"); - EVAL_PARAM_EXPR(actualReq.params, "xexpr", "x"); - EVAL_PARAM_EXPR(actualReq.params, "yexpr", "y"); - EVAL_PARAM_EXPR(actualReq.params, "zexpr", "z"); - -// process(actualReq); - _workQueue.push(actualReq); -} - -void OSGConverter::cancel(const std::string sendId) { -} - -void OSGConverter::invoke(const InvokeRequest& req) { - int nrThreads = 1; - if (req.params.find("threads") != req.params.end() && isNumeric(req.params.find("threads")->second.c_str(), 10)) { - nrThreads = strTo(req.params.find("threads")->second); - } - - _isRunning = true; - for (int i = 0; i < nrThreads; i++) { - _threads.insert(new tthread::thread(OSGConverter::run, this)); - } -} - -void OSGConverter::run(void* instance) { - OSGConverter* INSTANCE = (OSGConverter*)instance; - while(true) { - SendRequest req = INSTANCE->_workQueue.pop(); - if (INSTANCE->_isRunning) { - INSTANCE->process(req); - } else { - return; - } - } -} - -void OSGConverter::process(const SendRequest& req) { - -// std::cout << req; - - int width = 640; - int height = 480; - CAST_PARAM(req.params, width, "width", int); - CAST_PARAM(req.params, height, "height", int); - - assert(req.params.find("source") != req.params.end()); - assert(req.params.find("dest") != req.params.end()); - assert(req.params.find("format") != req.params.end()); - - std::string source = req.params.find("source")->second; - std::string dest = req.params.find("dest")->second; - std::string format = req.params.find("format")->second; - - bool autoRotate = true; - if (req.params.find("autorotate") != req.params.end()) { - if (boost::iequals(req.params.find("autorotate")->second, "off") || - boost::iequals(req.params.find("autorotate")->second, "0") || - boost::iequals(req.params.find("autorotate")->second, "false")) { - autoRotate = false; - } - } - - osg::ref_ptr model = setupGraph(source, autoRotate); - if (model->asGroup()->getNumChildren() == 0) { - reportFailure(req); - return; - } - - osg::ref_ptr sceneGraph = new osg::Group(); - sceneGraph->addChild(model); - - osgDB::ReaderWriter::WriteResult result; - if (osgDB::Registry::instance()->getReaderWriterForExtension(format) != NULL) { - // write as another 3D file - result = osgDB::Registry::instance()->writeNode(*sceneGraph, dest, osgDB::Registry::instance()->getOptions()); - if (result.success()) { - // we can know about success right here - reportSuccess(req); - return; - } - } - - /** - * If we failed to interpret the extension as another 3D file, try to make a screenshot. - */ - - ((osg::MatrixTransform*)model.get())->setMatrix(requestToModelPose(req)); - osg::BoundingSphere bs = model->getBound(); - -// osg::ref_ptr scale = new osg::MatrixTransform(); -// scale->setMatrix(osg::Matrix::scale(bs.radius() / 5, bs.radius() / 5, bs.radius() / 5)); -// scale->addChild(getOrigin()); -// sceneGraph->addChild(scale); - - osgViewer::ScreenCaptureHandler::CaptureOperation* cOp = new NameRespectingWriteToFile( - dest, - format, - osgViewer::ScreenCaptureHandler::WriteToFile::OVERWRITE, - req, this); - - osgViewer::ScreenCaptureHandler* captureHandler = new osgViewer::ScreenCaptureHandler(cOp, -1); - - osgViewer::Viewer viewer; - viewer.setSceneData(sceneGraph); - viewer.setCameraManipulator(new osgGA::TrackballManipulator()); - viewer.addEventHandler(captureHandler); - captureHandler->startCapture(); - - osg::DisplaySettings* ds = osg::DisplaySettings::instance().get(); - osg::ref_ptr traits = new osg::GraphicsContext::Traits(ds); - traits->width = width; - traits->height = height; - traits->pbuffer = true; - osg::ref_ptr gc = osg::GraphicsContext::createGraphicsContext(traits.get()); - - if (!gc.valid()) { - LOG(ERROR) << "Cannot create GraphicsContext!"; - return; - } - - GLenum pbuffer = gc->getTraits()->doubleBuffer ? GL_BACK : GL_FRONT; - - viewer.getCamera()->setGraphicsContext(gc.get()); - viewer.getCamera()->setViewport(new osg::Viewport(0,0,traits->width,traits->height)); - viewer.getCamera()->setDrawBuffer(pbuffer); - viewer.getCamera()->setReadBuffer(pbuffer); - - double zoom = 1; - CAST_PARAM(req.params, zoom, "zoom", double); - - // set background color - viewer.getCamera()->setClearColor(osg::Vec4f(1.0f,1.0f,1.0f,1.0f)); - viewer.getCamera()->setClearMask(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - viewer.getCameraManipulator()->setByMatrix(osg::Matrix::lookAt(osg::Vec3d(0,0,bs.radius() * (-3.4 * zoom)), // eye - (osg::Vec3d)bs.center(), // center - osg::Vec3d(0,1,0))); // up - -// viewer.home(); - - // perform one viewer iteration - viewer.realize(); - viewer.frame(); -} - -void OSGConverter::reportSuccess(const SendRequest& req) { - Event event(req); - if (event.name.length() == 0) - event.name = "convert"; - event.name += ".success"; - returnEvent(event); -} - -void OSGConverter::reportFailure(const SendRequest& req) { - Event event(req); - if (event.name.length() == 0) - event.name = "convert"; - event.name += ".failure"; - returnEvent(event); -} - -osg::Matrix OSGConverter::requestToModelPose(const SendRequest& req) { - double pitch = 0; - double roll = 0; - double yaw = 0; - double x = 0; - double y = 0; - double z = 0; - CAST_PARAM(req.params, pitch, "pitch", double); - CAST_PARAM(req.params, roll, "roll", double); - CAST_PARAM(req.params, yaw, "yaw", double); - CAST_PARAM(req.params, x, "x", double); - CAST_PARAM(req.params, y, "y", double); - CAST_PARAM(req.params, z, "z", double); - - osg::Matrix m = eulerToMatrix(pitch, roll, yaw) * osg::Matrix::translate(-1 * x, -1 * y, -1 * z); -#if 0 - dumpMatrix(m); -#endif - return m; -} - -osg::Matrix OSGConverter::requestToCamPose(const SendRequest& req) { -// double zoom = 1; -// CAST_PARAM(req.params, zoom, "zoom", double); -// osg::Matrix scale = osg::Matrix::scale(zoom, zoom, zoom); -// return scale; - osg::Matrix identity; - identity.makeIdentity(); - return identity; -} - -osg::ref_ptr OSGConverter::setupGraph(const std::string filename, bool autoRotate) { - - // get some privacy - tthread::lock_guard lock(_cacheMutex); - - /** - * root (model pose) - * - rotate (autoRotate to face largest side) - * - modelCenter (center model) - * - model (actual model) - */ - - long now = tthread::chrono::system_clock::now(); - - { - - // do we have it in the cache? - if (_models.find(filename) == _models.end()) { - osg::ref_ptr model = osgDB::readNodeFile(filename); - if (!model.valid()) { - LOG(ERROR) << "Cannot load model from " << filename; - return new osg::MatrixTransform(); - } - _models[filename] = std::make_pair(now, model); - } - _models[filename].first = now; - -#if 1 - // remove old models from cache - std::map > >::iterator modelIter = _models.begin(); - while(modelIter != _models.end()) { - // delete every model unused for 1 minutes - if (now - modelIter->second.first > 60000) { - _models.erase(modelIter++); - } else { - modelIter++; - } - } - -#endif - } - - osg::ref_ptr root = new osg::MatrixTransform(); - osg::ref_ptr rotate = new osg::MatrixTransform(); - osg::ref_ptr model = _models[filename].second; - - // translation matrix to move model into center - osg::ref_ptr modelCenter = new osg::MatrixTransform(); - modelCenter->addChild(model); - rotate->addChild(modelCenter); - - // move bounding sphere center into origin - osg::BoundingSphere bs = model->getBound(); - modelCenter->setMatrix(osg::Matrix::translate(bs.center() *= -1)); - - // get bounding box - osg::ComputeBoundsVisitor cbv; - osg::BoundingBox& bb(cbv.getBoundingBox()); - modelCenter->accept(cbv); - - if (autoRotate) { - double depth = bb.zMax() - bb.zMin(); - double width = bb.xMax() - bb.xMin(); - double height = bb.yMax() - bb.yMin(); - - double frontArea = width * height; - double sideArea = depth * height; - double topArea = depth * width; - - // rotate by multiples of 90deg to face largest area - if (frontArea < sideArea || frontArea < topArea) { - if (sideArea < topArea) { - // top needs to come to front -> rotate on x - rotate->setMatrix(osg::Matrix::rotate(M_PI_2, osg::Vec3f(1.0,0,0))); - } else { - // side needs to come to front - rotate->setMatrix(osg::Matrix::rotate(M_PI_2, osg::Vec3f(0,1.0,0))); - } - } - } - - // add rotation to root - root->addChild(rotate); - return root; -} - -osg::ref_ptr OSGConverter::getOrigin() { - osg::Geode* geode = new osg::Geode(); -// osg::StateSet* stateset = new osg::StateSet(); -// stateset->setMode(GL_LIGHTING, osg::StateAttribute::ON); -// geode->setStateSet(stateset); - - geode->addDrawable(new osg::ShapeDrawable(new osg::Sphere(osg::Vec3(0.0f,0.0f,0.0f),1))); - geode->addDrawable(new osg::ShapeDrawable(new osg::Box(osg::Vec3(10.0f,0.0f,0.0f),0.5))); - geode->addDrawable(new osg::ShapeDrawable(new osg::Box(osg::Vec3(0.0f,10.0f,0.0f),2))); - geode->addDrawable(new osg::ShapeDrawable(new osg::Box(osg::Vec3(0.0f,0.0f,10.0f),4))); - // geode->addDrawable(new osg::ShapeDrawable(new osg::Cone(osg::Vec3(4.0f,0.0f,0.0f),radius,height),hints)); - - return geode; -} - -osg::Matrix OSGConverter::eulerToMatrix(double pitch, double roll, double yaw) { - // see http://www.flipcode.com/documents/matrfaq.html#Q36 - osg::Matrix m; - m.makeIdentity(); - - double A = cos(pitch); - double B = sin(pitch); - double C = cos(roll); - double D = sin(roll); - double E = cos(yaw); - double F = sin(yaw); - - double AD = A * D; - double BD = B * D; - - m(0,0) = C * E; - m(0,1) = -C * F; - m(0,2) = -D; - m(1,0) = -BD * E + A * F; - m(1,1) = BD * F + A * E; - m(1,2) = -B * C; - m(2,0) = AD * E + B * F; - m(2,1) = -AD * F + B * E; - m(2,2) = A * C; - - m(0,3) = m(1,3) = m(2,3) = m(3,0) = m(3,1) = m(3,2) = 0; - m(3,3) = 1; - - return m; -} - -void OSGConverter::matrixToEuler(const osg::Matrix& m, double& pitch, double& roll, double& yaw) { - // see: http://www.flipcode.com/documents/matrfaq.html#Q37 - double angle_x, angle_z; - double D = -1 * asin(m(0,2)); /* Calculate Y-axis angle */ - double angle_y = D; - double C = cos(angle_y); - - /* Gimball lock? */ - if ( fabs( C ) > 0.005 ) { - double tr_x = m(2,2) / C; /* No, so get X-axis angle */ - double tr_y = -1 * m(1,2) / C; - angle_x = atan2( tr_y, tr_x ); - tr_x = m(0,0) / C; /* Get Z-axis angle */ - tr_y = -1 * m(0,1) / C; - angle_z = atan2( tr_y, tr_x ); - } else { - /* Gimball lock has occurred */ - angle_x = 0; /* Set X-axis angle to zero */ - double tr_x = m(1,1); /* And calculate Z-axis angle */ - double tr_y = m(1,0); - angle_z = atan2( tr_y, tr_x ); - } - - pitch = fmod(angle_x, 2 * M_PI ); /* Clamp all angles to range */ - roll = fmod( angle_y, 2 * M_PI ); - yaw = fmod( angle_z, 2 * M_PI ); -} - -void OSGConverter::dumpMatrix(const osg::Matrix& m) { - for (int i = 0; i < 4; i++) { - for (int j = 0; j < 4; j++) { - std::cout << ", " << m(i, j); - } - std::cout << std::endl; - } -} - -void OSGConverter::NameRespectingWriteToFile::operator()(const osg::Image& image, const unsigned int context_id) { - -// URL fileURL(_filename); -// fileURL.path() - - std::string tmpName = _filename; - size_t pathSep = _filename.find_last_of(PATH_SEPERATOR); - if (pathSep != std::string::npos) { - tmpName = _filename.substr(0, pathSep) + PATH_SEPERATOR + ".tmp" + _filename.substr(pathSep + 1, _filename.length() - pathSep - 1); - } - - bool success = osgDB::writeImageFile(image, tmpName); // <- no plugin to write to .tmp format - if (!success) { - _converter->reportFailure(_req); - return; - } - - if (pathSep != std::string::npos) { - int err = rename(tmpName.c_str(), _filename.c_str()); - if (err) { - _converter->reportFailure(_req); - } - } - - _converter->reportSuccess(_req); -} - -} \ No newline at end of file diff --git a/src/uscxml/plugins/invoker/graphics/openscenegraph/OSGConverter.h b/src/uscxml/plugins/invoker/graphics/openscenegraph/OSGConverter.h deleted file mode 100644 index f493e73..0000000 --- a/src/uscxml/plugins/invoker/graphics/openscenegraph/OSGConverter.h +++ /dev/null @@ -1,82 +0,0 @@ -#ifndef OSGCONVERTER_H_W09J90F0 -#define OSGCONVERTER_H_W09J90F0 - -#include -#include -#include - -#ifdef BUILD_AS_PLUGINS -#include "uscxml/plugins/Plugins.h" -#endif - -namespace uscxml { - -class OSGConverter : public InvokerImpl { -public: - OSGConverter(); - virtual ~OSGConverter(); - virtual boost::shared_ptr create(Interpreter* interpreter); - - virtual std::set getNames() { - std::set names; - names.insert("osgconverter"); - names.insert("osgconvert"); - names.insert("http://uscxml.tk.informatik.tu-darmstadt.de/#osgconverter"); - names.insert("http://uscxml.tk.informatik.tu-darmstadt.de/#osgconvert"); - return names; - } - - virtual Data getDataModelVariables(); - virtual void send(const SendRequest& req); - virtual void cancel(const std::string sendId); - virtual void invoke(const InvokeRequest& req); - - void reportSuccess(const SendRequest& req); - void reportFailure(const SendRequest& req); - - osg::Matrix requestToModelPose(const SendRequest& req); - osg::Matrix requestToCamPose(const SendRequest& req); - - static void dumpMatrix(const osg::Matrix& m); - static osg::Matrix eulerToMatrix(double pitch, double roll, double yaw); - static void matrixToEuler(const osg::Matrix& m, double& pitch, double& roll, double& yaw); - -protected: - class NameRespectingWriteToFile : public osgViewer::ScreenCaptureHandler::WriteToFile { - public: - NameRespectingWriteToFile(const std::string& filename, - const std::string& extension, - SavePolicy savePolicy, - const SendRequest& req, - OSGConverter* converter) : osgViewer::ScreenCaptureHandler::WriteToFile(filename, extension, savePolicy), - _req(req), _converter(converter) { - } - - virtual void operator()(const osg::Image& image, const unsigned int context_id); - SendRequest _req; - OSGConverter* _converter; - }; - - uscxml::concurrency::BlockingQueue _workQueue; - osg::ref_ptr setupGraph(const std::string filename, bool autoRotate = false); - osg::ref_ptr getOrigin(); - - std::map > > _models; - tthread::recursive_mutex _cacheMutex; - - std::set _threads; - - static void run(void*); - void process(const SendRequest& req); - - bool _isRunning; -}; - -#ifdef BUILD_AS_PLUGINS -PLUMA_INHERIT_PROVIDER(OSGConverter, Invoker); -#endif - -} - - -#endif /* end of include guard: OSGCONVERTER_H_W09J90F0 */ diff --git a/src/uscxml/plugins/invoker/graphics/openscenegraph/converter/OSGConverter.cpp b/src/uscxml/plugins/invoker/graphics/openscenegraph/converter/OSGConverter.cpp new file mode 100644 index 0000000..93a238c --- /dev/null +++ b/src/uscxml/plugins/invoker/graphics/openscenegraph/converter/OSGConverter.cpp @@ -0,0 +1,533 @@ +#include "OSGConverter.h" +#include +#include "uscxml/config.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#ifdef BUILD_AS_PLUGINS +#include +#endif + +#define EVAL_PARAM_EXPR(param, expr, key) \ +if (param.find(key) == param.end() && param.find(expr) != param.end() && _interpreter->getDataModel()) \ + param.insert(std::make_pair(key, _interpreter->getDataModel().evalAsString(param.find(expr)->second))); + +#define CAST_PARAM(param, var, key, type) \ +if (param.find(key) != param.end()) { \ + try { var = boost::lexical_cast(param.find(key)->second); } \ + catch(...) { LOG(ERROR) << "Attribute " key " of sendrequest to osgconverter is of invalid format: " << param.find(key)->second; } \ +} + + +namespace uscxml { + +#ifdef BUILD_AS_PLUGINS +PLUMA_CONNECTOR +bool connect(pluma::Host& host) { + host.add( new OSGConverterProvider() ); + return true; +} +#endif + +OSGConverter::OSGConverter() : _isRunning(false) { +// osg::setNotifyLevel(osg::DEBUG_FP); +} + +OSGConverter::~OSGConverter() { + _isRunning = false; + std::set::iterator threadIter = _threads.begin(); + while(threadIter != _threads.end()) { + (*threadIter)->join(); + } +}; + +boost::shared_ptr OSGConverter::create(Interpreter* interpreter) { + boost::shared_ptr invoker = boost::shared_ptr(new OSGConverter()); + invoker->_interpreter = interpreter; + return invoker; +} + +Data OSGConverter::getDataModelVariables() { + Data data; + return data; +} + +void OSGConverter::send(const SendRequest& req) { + + /** + * we have to resolve all datamodel dependent strings first as + * we cannot access the datamodel from within another thread without locking + */ + + // make a copy + SendRequest actualReq(req); + + if (actualReq.params.find("source") == actualReq.params.end()) { + // no explicit source + if (actualReq.params.find("sourceexpr") != actualReq.params.end() && _interpreter->getDataModel()) { + actualReq.params.insert(std::make_pair("source", _interpreter->getDataModel().evalAsString(actualReq.params.find("sourceexpr")->second))); + } else { + LOG(ERROR) << "SendRequests for osginvoker missing source or sourceExpr and datamodel"; + return; + } + } + + if (actualReq.params.find("dest") == actualReq.params.end()) { + // no explicit destination + if (actualReq.params.find("destexpr") != actualReq.params.end() && _interpreter->getDataModel()) { + actualReq.params.insert(std::make_pair("dest", _interpreter->getDataModel().evalAsString(actualReq.params.find("destexpr")->second))); + } else { + LOG(ERROR) << "SendRequests for osginvoker missing dest or destExpr and datamodel"; + return; + } + } + + boost::algorithm::replace_all(actualReq.params.find("dest")->second, "//", "/"); + boost::algorithm::replace_all(actualReq.params.find("dest")->second, "\\\\", "\\"); + + if (actualReq.params.find("autorotate") == actualReq.params.end()) { + if (actualReq.params.find("autorotateexpr") != actualReq.params.end()) { + if (_interpreter->getDataModel()) { + actualReq.params.insert(std::make_pair("autorotate", _interpreter->getDataModel().evalAsString(actualReq.params.find("autorotateexpr")->second))); + } else { + LOG(ERROR) << "SendRequests for osginvoker ncludes autorotateexpr but no datamodel is specified"; + return; + } + } + } + + if (actualReq.params.find("format") == actualReq.params.end()) { + // no explicit format + if (actualReq.params.find("formatexpr") != actualReq.params.end() && _interpreter->getDataModel()) { + actualReq.params.insert(std::make_pair("format", _interpreter->getDataModel().evalAsString(actualReq.params.find("formatexpr")->second))); + } else { + std::string format; + size_t lastDot; + std::string dest = req.params.find("dest")->second; + if ((lastDot = dest.find_last_of(".")) != std::string::npos) { + lastDot++; + format = dest.substr(lastDot, dest.length() - lastDot); + } + if (format.length() == 0 || format.find_last_of(PATH_SEPERATOR) != std::string::npos) { + // empty format or pathseperator in format + format = "png"; + } + actualReq.params.insert(std::make_pair("format", format)); + } + } + +// assert(osgDB::Registry::instance()->getReaderWriterForExtension("png")); +// osgDB::Registry::ReaderWriterList formatList = osgDB::Registry::instance()->getReaderWriterList(); +// for (int i = 0; i < formatList.size(); i++) { +// std::map funcDesc = formatList[i]->supportedProtocols(); +// std::map::iterator funcDescIter = funcDesc.begin(); +// while(funcDescIter != funcDesc.end()) { +// std::cout << funcDescIter->first << ": " << funcDescIter->second << std::endl; +// funcDescIter++; +// } +// } + + EVAL_PARAM_EXPR(actualReq.params, "heightexpr", "height"); + EVAL_PARAM_EXPR(actualReq.params, "widthexpr", "width"); + EVAL_PARAM_EXPR(actualReq.params, "pitchexpr", "pitch"); + EVAL_PARAM_EXPR(actualReq.params, "rollexpr", "roll"); + EVAL_PARAM_EXPR(actualReq.params, "yawexpr", "yaw"); + EVAL_PARAM_EXPR(actualReq.params, "zoomexpr", "zoom"); + EVAL_PARAM_EXPR(actualReq.params, "xexpr", "x"); + EVAL_PARAM_EXPR(actualReq.params, "yexpr", "y"); + EVAL_PARAM_EXPR(actualReq.params, "zexpr", "z"); + +// process(actualReq); + _workQueue.push(actualReq); +} + +void OSGConverter::cancel(const std::string sendId) { +} + +void OSGConverter::invoke(const InvokeRequest& req) { + int nrThreads = 1; + if (req.params.find("threads") != req.params.end() && isNumeric(req.params.find("threads")->second.c_str(), 10)) { + nrThreads = strTo(req.params.find("threads")->second); + } + + _isRunning = true; + for (int i = 0; i < nrThreads; i++) { + _threads.insert(new tthread::thread(OSGConverter::run, this)); + } +} + +void OSGConverter::run(void* instance) { + OSGConverter* INSTANCE = (OSGConverter*)instance; + while(true) { + SendRequest req = INSTANCE->_workQueue.pop(); + if (INSTANCE->_isRunning) { + INSTANCE->process(req); + } else { + return; + } + } +} + +void OSGConverter::process(const SendRequest& req) { + +// std::cout << req; + + int width = 640; + int height = 480; + CAST_PARAM(req.params, width, "width", int); + CAST_PARAM(req.params, height, "height", int); + + assert(req.params.find("source") != req.params.end()); + assert(req.params.find("dest") != req.params.end()); + assert(req.params.find("format") != req.params.end()); + + std::string source = req.params.find("source")->second; + std::string dest = req.params.find("dest")->second; + std::string format = req.params.find("format")->second; + + bool autoRotate = true; + if (req.params.find("autorotate") != req.params.end()) { + if (boost::iequals(req.params.find("autorotate")->second, "off") || + boost::iequals(req.params.find("autorotate")->second, "0") || + boost::iequals(req.params.find("autorotate")->second, "false")) { + autoRotate = false; + } + } + + osg::ref_ptr model = setupGraph(source, autoRotate); + if (model->asGroup()->getNumChildren() == 0) { + reportFailure(req); + return; + } + + osg::ref_ptr sceneGraph = new osg::Group(); + sceneGraph->addChild(model); + + osgDB::ReaderWriter::WriteResult result; + if (osgDB::Registry::instance()->getReaderWriterForExtension(format) != NULL) { + // write as another 3D file + result = osgDB::Registry::instance()->writeNode(*sceneGraph, dest, osgDB::Registry::instance()->getOptions()); + if (result.success()) { + // we can know about success right here + reportSuccess(req); + return; + } + } + + /** + * If we failed to interpret the extension as another 3D file, try to make a screenshot. + */ + + ((osg::MatrixTransform*)model.get())->setMatrix(requestToModelPose(req)); + osg::BoundingSphere bs = model->getBound(); + +// osg::ref_ptr scale = new osg::MatrixTransform(); +// scale->setMatrix(osg::Matrix::scale(bs.radius() / 5, bs.radius() / 5, bs.radius() / 5)); +// scale->addChild(getOrigin()); +// sceneGraph->addChild(scale); + + osgViewer::ScreenCaptureHandler::CaptureOperation* cOp = new NameRespectingWriteToFile( + dest, + format, + osgViewer::ScreenCaptureHandler::WriteToFile::OVERWRITE, + req, this); + + osgViewer::ScreenCaptureHandler* captureHandler = new osgViewer::ScreenCaptureHandler(cOp, -1); + + osgViewer::Viewer viewer; + viewer.setSceneData(sceneGraph); + viewer.setCameraManipulator(new osgGA::TrackballManipulator()); + viewer.addEventHandler(captureHandler); + captureHandler->startCapture(); + + osg::DisplaySettings* ds = osg::DisplaySettings::instance().get(); + osg::ref_ptr traits = new osg::GraphicsContext::Traits(ds); + traits->width = width; + traits->height = height; + traits->pbuffer = true; + osg::ref_ptr gc = osg::GraphicsContext::createGraphicsContext(traits.get()); + + if (!gc.valid()) { + LOG(ERROR) << "Cannot create GraphicsContext!"; + return; + } + + GLenum pbuffer = gc->getTraits()->doubleBuffer ? GL_BACK : GL_FRONT; + + viewer.getCamera()->setGraphicsContext(gc.get()); + viewer.getCamera()->setViewport(new osg::Viewport(0,0,traits->width,traits->height)); + viewer.getCamera()->setDrawBuffer(pbuffer); + viewer.getCamera()->setReadBuffer(pbuffer); + + double zoom = 1; + CAST_PARAM(req.params, zoom, "zoom", double); + + // set background color + viewer.getCamera()->setClearColor(osg::Vec4f(1.0f,1.0f,1.0f,1.0f)); + viewer.getCamera()->setClearMask(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + viewer.getCameraManipulator()->setByMatrix(osg::Matrix::lookAt(osg::Vec3d(0,0,bs.radius() * (-3.4 * zoom)), // eye + (osg::Vec3d)bs.center(), // center + osg::Vec3d(0,1,0))); // up + +// viewer.home(); + + // perform one viewer iteration + viewer.realize(); + viewer.frame(); +} + +void OSGConverter::reportSuccess(const SendRequest& req) { + Event event(req); + if (event.name.length() == 0) + event.name = "convert"; + event.name += ".success"; + returnEvent(event); +} + +void OSGConverter::reportFailure(const SendRequest& req) { + Event event(req); + if (event.name.length() == 0) + event.name = "convert"; + event.name += ".failure"; + returnEvent(event); +} + +osg::Matrix OSGConverter::requestToModelPose(const SendRequest& req) { + double pitch = 0; + double roll = 0; + double yaw = 0; + double x = 0; + double y = 0; + double z = 0; + CAST_PARAM(req.params, pitch, "pitch", double); + CAST_PARAM(req.params, roll, "roll", double); + CAST_PARAM(req.params, yaw, "yaw", double); + CAST_PARAM(req.params, x, "x", double); + CAST_PARAM(req.params, y, "y", double); + CAST_PARAM(req.params, z, "z", double); + + osg::Matrix m = eulerToMatrix(pitch, roll, yaw) * osg::Matrix::translate(-1 * x, -1 * y, -1 * z); +#if 0 + dumpMatrix(m); +#endif + return m; +} + +osg::Matrix OSGConverter::requestToCamPose(const SendRequest& req) { +// double zoom = 1; +// CAST_PARAM(req.params, zoom, "zoom", double); +// osg::Matrix scale = osg::Matrix::scale(zoom, zoom, zoom); +// return scale; + osg::Matrix identity; + identity.makeIdentity(); + return identity; +} + +osg::ref_ptr OSGConverter::setupGraph(const std::string filename, bool autoRotate) { + + // get some privacy + tthread::lock_guard lock(_cacheMutex); + + /** + * root (model pose) + * - rotate (autoRotate to face largest side) + * - modelCenter (center model) + * - model (actual model) + */ + + long now = tthread::chrono::system_clock::now(); + + { + + // do we have it in the cache? + if (_models.find(filename) == _models.end()) { + osg::ref_ptr model = osgDB::readNodeFile(filename); + if (!model.valid()) { + LOG(ERROR) << "Cannot load model from " << filename; + return new osg::MatrixTransform(); + } + _models[filename] = std::make_pair(now, model); + } + _models[filename].first = now; + +#if 1 + // remove old models from cache + std::map > >::iterator modelIter = _models.begin(); + while(modelIter != _models.end()) { + // delete every model unused for 1 minutes + if (now - modelIter->second.first > 60000) { + _models.erase(modelIter++); + } else { + modelIter++; + } + } + +#endif + } + + osg::ref_ptr root = new osg::MatrixTransform(); + osg::ref_ptr rotate = new osg::MatrixTransform(); + osg::ref_ptr model = _models[filename].second; + + // translation matrix to move model into center + osg::ref_ptr modelCenter = new osg::MatrixTransform(); + modelCenter->addChild(model); + rotate->addChild(modelCenter); + + // move bounding sphere center into origin + osg::BoundingSphere bs = model->getBound(); + modelCenter->setMatrix(osg::Matrix::translate(bs.center() *= -1)); + + // get bounding box + osg::ComputeBoundsVisitor cbv; + osg::BoundingBox& bb(cbv.getBoundingBox()); + modelCenter->accept(cbv); + + if (autoRotate) { + double depth = bb.zMax() - bb.zMin(); + double width = bb.xMax() - bb.xMin(); + double height = bb.yMax() - bb.yMin(); + + double frontArea = width * height; + double sideArea = depth * height; + double topArea = depth * width; + + // rotate by multiples of 90deg to face largest area + if (frontArea < sideArea || frontArea < topArea) { + if (sideArea < topArea) { + // top needs to come to front -> rotate on x + rotate->setMatrix(osg::Matrix::rotate(M_PI_2, osg::Vec3f(1.0,0,0))); + } else { + // side needs to come to front + rotate->setMatrix(osg::Matrix::rotate(M_PI_2, osg::Vec3f(0,1.0,0))); + } + } + } + + // add rotation to root + root->addChild(rotate); + return root; +} + +osg::ref_ptr OSGConverter::getOrigin() { + osg::Geode* geode = new osg::Geode(); +// osg::StateSet* stateset = new osg::StateSet(); +// stateset->setMode(GL_LIGHTING, osg::StateAttribute::ON); +// geode->setStateSet(stateset); + + geode->addDrawable(new osg::ShapeDrawable(new osg::Sphere(osg::Vec3(0.0f,0.0f,0.0f),1))); + geode->addDrawable(new osg::ShapeDrawable(new osg::Box(osg::Vec3(10.0f,0.0f,0.0f),0.5))); + geode->addDrawable(new osg::ShapeDrawable(new osg::Box(osg::Vec3(0.0f,10.0f,0.0f),2))); + geode->addDrawable(new osg::ShapeDrawable(new osg::Box(osg::Vec3(0.0f,0.0f,10.0f),4))); + // geode->addDrawable(new osg::ShapeDrawable(new osg::Cone(osg::Vec3(4.0f,0.0f,0.0f),radius,height),hints)); + + return geode; +} + +osg::Matrix OSGConverter::eulerToMatrix(double pitch, double roll, double yaw) { + // see http://www.flipcode.com/documents/matrfaq.html#Q36 + osg::Matrix m; + m.makeIdentity(); + + double A = cos(pitch); + double B = sin(pitch); + double C = cos(roll); + double D = sin(roll); + double E = cos(yaw); + double F = sin(yaw); + + double AD = A * D; + double BD = B * D; + + m(0,0) = C * E; + m(0,1) = -C * F; + m(0,2) = -D; + m(1,0) = -BD * E + A * F; + m(1,1) = BD * F + A * E; + m(1,2) = -B * C; + m(2,0) = AD * E + B * F; + m(2,1) = -AD * F + B * E; + m(2,2) = A * C; + + m(0,3) = m(1,3) = m(2,3) = m(3,0) = m(3,1) = m(3,2) = 0; + m(3,3) = 1; + + return m; +} + +void OSGConverter::matrixToEuler(const osg::Matrix& m, double& pitch, double& roll, double& yaw) { + // see: http://www.flipcode.com/documents/matrfaq.html#Q37 + double angle_x, angle_z; + double D = -1 * asin(m(0,2)); /* Calculate Y-axis angle */ + double angle_y = D; + double C = cos(angle_y); + + /* Gimball lock? */ + if ( fabs( C ) > 0.005 ) { + double tr_x = m(2,2) / C; /* No, so get X-axis angle */ + double tr_y = -1 * m(1,2) / C; + angle_x = atan2( tr_y, tr_x ); + tr_x = m(0,0) / C; /* Get Z-axis angle */ + tr_y = -1 * m(0,1) / C; + angle_z = atan2( tr_y, tr_x ); + } else { + /* Gimball lock has occurred */ + angle_x = 0; /* Set X-axis angle to zero */ + double tr_x = m(1,1); /* And calculate Z-axis angle */ + double tr_y = m(1,0); + angle_z = atan2( tr_y, tr_x ); + } + + pitch = fmod(angle_x, 2 * M_PI ); /* Clamp all angles to range */ + roll = fmod( angle_y, 2 * M_PI ); + yaw = fmod( angle_z, 2 * M_PI ); +} + +void OSGConverter::dumpMatrix(const osg::Matrix& m) { + for (int i = 0; i < 4; i++) { + for (int j = 0; j < 4; j++) { + std::cout << ", " << m(i, j); + } + std::cout << std::endl; + } +} + +void OSGConverter::NameRespectingWriteToFile::operator()(const osg::Image& image, const unsigned int context_id) { + +// URL fileURL(_filename); +// fileURL.path() + + std::string tmpName = _filename; + size_t pathSep = _filename.find_last_of(PATH_SEPERATOR); + if (pathSep != std::string::npos) { + tmpName = _filename.substr(0, pathSep) + PATH_SEPERATOR + ".tmp" + _filename.substr(pathSep + 1, _filename.length() - pathSep - 1); + } + + bool success = osgDB::writeImageFile(image, tmpName); // <- no plugin to write to .tmp format + if (!success) { + _converter->reportFailure(_req); + return; + } + + if (pathSep != std::string::npos) { + int err = rename(tmpName.c_str(), _filename.c_str()); + if (err) { + _converter->reportFailure(_req); + } + } + + _converter->reportSuccess(_req); +} + +} \ No newline at end of file diff --git a/src/uscxml/plugins/invoker/graphics/openscenegraph/converter/OSGConverter.h b/src/uscxml/plugins/invoker/graphics/openscenegraph/converter/OSGConverter.h new file mode 100644 index 0000000..28c908d --- /dev/null +++ b/src/uscxml/plugins/invoker/graphics/openscenegraph/converter/OSGConverter.h @@ -0,0 +1,82 @@ +#ifndef OSGCONVERTER_H_W09J90F0 +#define OSGCONVERTER_H_W09J90F0 + +#include +#include +#include + +#ifdef BUILD_AS_PLUGINS +#include "uscxml/plugins/Plugins.h" +#endif + +namespace uscxml { + +class OSGConverter : public InvokerImpl { +public: + OSGConverter(); + virtual ~OSGConverter(); + virtual boost::shared_ptr create(Interpreter* interpreter); + + virtual std::set getNames() { + std::set names; + names.insert("osgconverter"); + names.insert("osgconvert"); + names.insert("http://uscxml.tk.informatik.tu-darmstadt.de/#osgconverter"); + names.insert("http://uscxml.tk.informatik.tu-darmstadt.de/#osgconvert"); + return names; + } + + virtual Data getDataModelVariables(); + virtual void send(const SendRequest& req); + virtual void cancel(const std::string sendId); + virtual void invoke(const InvokeRequest& req); + + void reportSuccess(const SendRequest& req); + void reportFailure(const SendRequest& req); + + osg::Matrix requestToModelPose(const SendRequest& req); + osg::Matrix requestToCamPose(const SendRequest& req); + + static void dumpMatrix(const osg::Matrix& m); + static osg::Matrix eulerToMatrix(double pitch, double roll, double yaw); + static void matrixToEuler(const osg::Matrix& m, double& pitch, double& roll, double& yaw); + +protected: + class NameRespectingWriteToFile : public osgViewer::ScreenCaptureHandler::WriteToFile { + public: + NameRespectingWriteToFile(const std::string& filename, + const std::string& extension, + SavePolicy savePolicy, + const SendRequest& req, + OSGConverter* converter) : osgViewer::ScreenCaptureHandler::WriteToFile(filename, extension, savePolicy), + _req(req), _converter(converter) { + } + + virtual void operator()(const osg::Image& image, const unsigned int context_id); + SendRequest _req; + OSGConverter* _converter; + }; + + uscxml::concurrency::BlockingQueue _workQueue; + osg::ref_ptr setupGraph(const std::string filename, bool autoRotate = false); + osg::ref_ptr getOrigin(); + + std::map > > _models; + tthread::recursive_mutex _cacheMutex; + + std::set _threads; + + static void run(void*); + void process(const SendRequest& req); + + bool _isRunning; +}; + +#ifdef BUILD_AS_PLUGINS +PLUMA_INHERIT_PROVIDER(OSGConverter, InvokerImpl); +#endif + +} + + +#endif /* end of include guard: OSGCONVERTER_H_W09J90F0 */ diff --git a/src/uscxml/plugins/invoker/miles/MilesSessionInvoker.h b/src/uscxml/plugins/invoker/miles/MilesSessionInvoker.h index cb3e9ee..fa66038 100644 --- a/src/uscxml/plugins/invoker/miles/MilesSessionInvoker.h +++ b/src/uscxml/plugins/invoker/miles/MilesSessionInvoker.h @@ -91,7 +91,7 @@ protected: }; #ifdef BUILD_AS_PLUGINS -PLUMA_INHERIT_PROVIDER(MilesSessionInvoker, Invoker); +PLUMA_INHERIT_PROVIDER(MilesSessionInvoker, InvokerImpl); #endif } diff --git a/src/uscxml/plugins/invoker/sample/SampleInvoker.h b/src/uscxml/plugins/invoker/sample/SampleInvoker.h index 018dfc5..d689bda 100644 --- a/src/uscxml/plugins/invoker/sample/SampleInvoker.h +++ b/src/uscxml/plugins/invoker/sample/SampleInvoker.h @@ -31,7 +31,7 @@ protected: }; #ifdef BUILD_AS_PLUGINS -PLUMA_INHERIT_PROVIDER(SampleInvoker, Invoker); +PLUMA_INHERIT_PROVIDER(SampleInvoker, InvokerImpl); #endif } diff --git a/src/uscxml/plugins/invoker/sqlite3/Sqlite3Invoker.h b/src/uscxml/plugins/invoker/sqlite3/Sqlite3Invoker.h index f2ae915..505d263 100644 --- a/src/uscxml/plugins/invoker/sqlite3/Sqlite3Invoker.h +++ b/src/uscxml/plugins/invoker/sqlite3/Sqlite3Invoker.h @@ -31,7 +31,7 @@ protected: }; #ifdef BUILD_AS_PLUGINS -PLUMA_INHERIT_PROVIDER(Sqlite3Invoker, Invoker); +PLUMA_INHERIT_PROVIDER(Sqlite3Invoker, InvokerImpl); #endif } diff --git a/src/uscxml/plugins/invoker/system/SystemInvoker.h b/src/uscxml/plugins/invoker/system/SystemInvoker.h index 1440e79..67bd1a9 100644 --- a/src/uscxml/plugins/invoker/system/SystemInvoker.h +++ b/src/uscxml/plugins/invoker/system/SystemInvoker.h @@ -31,7 +31,7 @@ protected: }; #ifdef BUILD_AS_PLUGINS -PLUMA_INHERIT_PROVIDER(SystemInvoker, Invoker); +PLUMA_INHERIT_PROVIDER(SystemInvoker, InvokerImpl); #endif } diff --git a/src/uscxml/server/InterpreterServlet.cpp b/src/uscxml/server/InterpreterServlet.cpp new file mode 100644 index 0000000..fb8a6ef --- /dev/null +++ b/src/uscxml/server/InterpreterServlet.cpp @@ -0,0 +1,34 @@ +#include "InterpreterServlet.h" +#include "uscxml/Interpreter.h" + +namespace uscxml { + +InterpreterServlet::InterpreterServlet(Interpreter* interpreter) { + _interpreter = interpreter; + + std::stringstream path; + path << _interpreter->getName(); + int i = 2; + while(!HTTPServer::registerServlet(path.str(), this)) { + path.clear(); + path.str(); + path << _interpreter->getName() << i++; + } + _path = path.str(); +} + +void InterpreterServlet::httpRecvRequest(const HTTPServer::Request& req) { + tthread::lock_guard lock(_mutex); + + // evhttp_request_own(req.curlReq); + + _requests[toStr((uintptr_t)req.curlReq)] = req; + + Event event = req; + + event.name = "http." + event.data.compound["type"].atom; + event.origin = toStr((uintptr_t)req.curlReq); + _interpreter->receive(event); +} + +} \ No newline at end of file diff --git a/src/uscxml/server/InterpreterServlet.h b/src/uscxml/server/InterpreterServlet.h new file mode 100644 index 0000000..7235466 --- /dev/null +++ b/src/uscxml/server/InterpreterServlet.h @@ -0,0 +1,46 @@ +#ifndef INTERPRETERSERVLET_H_XQLWNMH4 +#define INTERPRETERSERVLET_H_XQLWNMH4 + +#include "HTTPServer.h" + +namespace uscxml { + +class Interpreter; + +class InterpreterServlet : public HTTPServlet { +public: + InterpreterServlet(Interpreter* interpreter); + virtual void httpRecvRequest(const HTTPServer::Request& req); + + std::string getPath() { + return _path; + } + std::string getURL() { + return _url; + } + void setURL(const std::string& url) { + _url = url; + } + bool canAdaptPath() { return false; } + + std::map& getRequests() { + return _requests; + } + tthread::recursive_mutex& getMutex() { + return _mutex; + } + +protected: + Interpreter* _interpreter; + + tthread::recursive_mutex _mutex; + std::map _requests; + std::string _path; + std::string _url; + +}; + +} + + +#endif /* end of include guard: INTERPRETERSERVLET_H_XQLWNMH4 */ diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 2bf1525..db27706 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -22,7 +22,7 @@ if (V8_FOUND) add_test(test-ecmascript ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/mmi-browser ${CMAKE_SOURCE_DIR}/test/samples/uscxml/test-ecmascript.scxml) endif() -if (OPENSCENEGRAPH_FOUND) +if (OPENSCENEGRAPH_FOUND AND OFF) add_executable(test-osg src/test-osg.cpp) target_link_libraries(test-osg uscxml) set_target_properties(test-osg PROPERTIES FOLDER "Tests") -- cgit v0.12