diff --git a/CMakeLists.txt b/CMakeLists.txt index 26c7f30b87..81b859e460 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -55,16 +55,18 @@ set(DEPENDENT_LIBS ${DEPENDENT_LIBS} Ghoul) #set(SGCT_ROOT_DIR "$ENV{SGCT_ROOT_DIR}") #set(SGCT_ROOT_DIR "C:/Program Files/SGCT/SGCT_2.0.7") #set(SGCT_ROOT_DIR "C:/Program Files (x86)/SGCT/SGCT_2.0.5_x86") -set(SGCT_ROOT_DIR "C:/Program Files/SGCT/SGCT_2.0.7") -add_definitions(-D__WIN32__) +#set(SGCT_ROOT_DIR "C:/Program Files/SGCT/SGCT_2.0.7") + +#add_definitions(-D__WIN32__) add_definitions(-DGLEW_STATIC) -include_directories("${SGCT_ROOT_DIR}/include") +include_directories("${OPENSPACE_EXT_DIR}/sgct/include") #set(CMAKE_LIBRARY_PATH ${CMAKE_LIBRARY_PATH} ${SGCT_ROOT_DOR}/bin/lib/msvc11) set(DEPENDENT_LIBS ${DEPENDENT_LIBS} - "Ws2_32.lib" - optimized "${SGCT_ROOT_DIR}/lib/msvc11_x64/sgct.lib" - debug "${SGCT_ROOT_DIR}/lib/msvc11_x64/sgctd.lib" +# "Ws2_32.lib" +# optimized "${SGCT_ROOT_DIR}/lib/msvc11_x64/sgct.lib" +# debug "${SGCT_ROOT_DIR}/lib/msvc11_x64/sgctd.lib" + ${OPENSPACE_EXT_DIR}/sgct/lib/libsgct_cpp11.a ) #add_subdirectory(${SGCT_ROOT_DIR}) @@ -78,18 +80,18 @@ include_directories(${GLM_INCLUDE_DIRS}) # OpenGL #find_package(OpenGL REQUIRED) #include_directories(${OPENGL_INCLUDE_DIRS}) -#set(DEPENDENT_LIBS ${DEPENDENT_LIBS} ${OPENGL_LIBRARIES}) +set(DEPENDENT_LIBS ${DEPENDENT_LIBS} ${OPENGL_LIBRARIES}) # GLEW #find_package(GLEW REQUIRED) #include_directories(${GLEW_INCLUDE_DIRECTORIES}) -#set(DEPENDENT_LIBS ${DEPENDENT_LIBS} ${GLEW_LIBRARIES}) +set(DEPENDENT_LIBS ${DEPENDENT_LIBS} ${GLEW_LIBRARIES}) # Lua set(LUA_ROOT_DIR "${GHOUL_ROOT_DIR}/ext/lua") include_directories("${LUA_ROOT_DIR}/include") #add_subdirectory(${LUA_ROOT_DIR}) -#set(DEPENDENT_LIBS ${DEPENDENT_LIBS} Lua) +set(DEPENDENT_LIBS ${DEPENDENT_LIBS} Lua) # Spice set(SPICE_ROOT_DIR "${OPENSPACE_EXT_DIR}/spice") @@ -97,13 +99,26 @@ include_directories("${SPICE_ROOT_DIR}/include") add_subdirectory(${SPICE_ROOT_DIR}) set(DEPENDENT_LIBS ${DEPENDENT_LIBS} Spice) +# Threads +find_library(PTHREADS_LIB pthread) +set(DEPENDENT_LIBS ${DEPENDENT_LIBS} ${PTHREADS_LIB}) + if (APPLE) include_directories(/Developer/Headers/FlatCarbon) find_library(CARBON_LIBRARY Carbon) - find_library(COCOA_LIBRARY Carbon) + find_library(COCOA_LIBRARY Cocoa) find_library(APP_SERVICES_LIBRARY ApplicationServices) - mark_as_advanced(CARBON_LIBRARY COCOA_LIBRARY APP_SERVICES_LIBRARY) - set(DEPENDENT_LIBS ${CARBON_LIBRARY} ${COCOA_LIBRARY} ${APP_SERVICES_LIBRARY}) + find_library(APPKIT_LIBRARY AppKit) + find_library(IOKIT_LIBRARY IOKit) + mark_as_advanced(CARBON_LIBRARY COCOA_LIBRARY APP_SERVICES_LIBRARY IOKIT_LIBRARY) + set(DEPENDENT_LIBS + ${DEPENDENT_LIBS} + ${CARBON_LIBRARY} + ${APPKIT_LIBRARY} + ${COCOA_LIBRARY} + ${APP_SERVICES_LIBRARY} + ${IOKIT_LIBRARY} + ) endif () ######################################################################################### diff --git a/ext/ghoul b/ext/ghoul index c8813d08fa..270056597a 160000 --- a/ext/ghoul +++ b/ext/ghoul @@ -1 +1 @@ -Subproject commit c8813d08fa2d86d13529f5674ee7198377ba4c0a +Subproject commit 270056597af3b843164434561b31c3556f659054 diff --git a/ext/tinythread.cpp b/ext/tinythread.cpp new file mode 100644 index 0000000000..5b5bd41cf4 --- /dev/null +++ b/ext/tinythread.cpp @@ -0,0 +1,303 @@ +/* -*- mode: c++; tab-width: 2; indent-tabs-mode: nil; -*- +Copyright (c) 2010-2012 Marcus Geelnard + +This software is provided 'as-is', without any express or implied +warranty. In no event will the authors be held liable for any damages +arising from the use of this software. + +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it +freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + + 3. This notice may not be removed or altered from any source + distribution. +*/ + +#include +#include "tinythread.h" + +#if defined(_TTHREAD_POSIX_) + #include + #include +#elif defined(_TTHREAD_WIN32_) + #include +#endif + + +namespace tthread { + +//------------------------------------------------------------------------------ +// condition_variable +//------------------------------------------------------------------------------ +// NOTE 1: The Win32 implementation of the condition_variable class is based on +// the corresponding implementation in GLFW, which in turn is based on a +// description by Douglas C. Schmidt and Irfan Pyarali: +// http://www.cs.wustl.edu/~schmidt/win32-cv-1.html +// +// NOTE 2: Windows Vista actually has native support for condition variables +// (InitializeConditionVariable, WakeConditionVariable, etc), but we want to +// be portable with pre-Vista Windows versions, so TinyThread++ does not use +// Vista condition variables. +//------------------------------------------------------------------------------ + +#if defined(_TTHREAD_WIN32_) + #define _CONDITION_EVENT_ONE 0 + #define _CONDITION_EVENT_ALL 1 +#endif + +#if defined(_TTHREAD_WIN32_) +condition_variable::condition_variable() : mWaitersCount(0) +{ + mEvents[_CONDITION_EVENT_ONE] = CreateEvent(NULL, FALSE, FALSE, NULL); + mEvents[_CONDITION_EVENT_ALL] = CreateEvent(NULL, TRUE, FALSE, NULL); + InitializeCriticalSection(&mWaitersCountLock); +} +#endif + +#if defined(_TTHREAD_WIN32_) +condition_variable::~condition_variable() +{ + CloseHandle(mEvents[_CONDITION_EVENT_ONE]); + CloseHandle(mEvents[_CONDITION_EVENT_ALL]); + DeleteCriticalSection(&mWaitersCountLock); +} +#endif + +#if defined(_TTHREAD_WIN32_) +void condition_variable::_wait() +{ + // Wait for either event to become signaled due to notify_one() or + // notify_all() being called + int result = WaitForMultipleObjects(2, mEvents, FALSE, INFINITE); + + // Check if we are the last waiter + EnterCriticalSection(&mWaitersCountLock); + -- mWaitersCount; + bool lastWaiter = (result == (WAIT_OBJECT_0 + _CONDITION_EVENT_ALL)) && + (mWaitersCount == 0); + LeaveCriticalSection(&mWaitersCountLock); + + // If we are the last waiter to be notified to stop waiting, reset the event + if(lastWaiter) + ResetEvent(mEvents[_CONDITION_EVENT_ALL]); +} +#endif + +#if defined(_TTHREAD_WIN32_) +void condition_variable::notify_one() +{ + // Are there any waiters? + EnterCriticalSection(&mWaitersCountLock); + bool haveWaiters = (mWaitersCount > 0); + LeaveCriticalSection(&mWaitersCountLock); + + // If we have any waiting threads, send them a signal + if(haveWaiters) + SetEvent(mEvents[_CONDITION_EVENT_ONE]); +} +#endif + +#if defined(_TTHREAD_WIN32_) +void condition_variable::notify_all() +{ + // Are there any waiters? + EnterCriticalSection(&mWaitersCountLock); + bool haveWaiters = (mWaitersCount > 0); + LeaveCriticalSection(&mWaitersCountLock); + + // If we have any waiting threads, send them a signal + if(haveWaiters) + SetEvent(mEvents[_CONDITION_EVENT_ALL]); +} +#endif + + +//------------------------------------------------------------------------------ +// POSIX pthread_t to unique thread::id mapping logic. +// Note: Here we use a global thread safe std::map to convert instances of +// pthread_t to small thread identifier numbers (unique within one process). +// This method should be portable across different POSIX implementations. +//------------------------------------------------------------------------------ + +#if defined(_TTHREAD_POSIX_) +static thread::id _pthread_t_to_ID(const pthread_t &aHandle) +{ + static mutex idMapLock; + static std::map idMap; + static unsigned long int idCount(1); + + lock_guard guard(idMapLock); + if(idMap.find(aHandle) == idMap.end()) + idMap[aHandle] = idCount ++; + return thread::id(idMap[aHandle]); +} +#endif // _TTHREAD_POSIX_ + + +//------------------------------------------------------------------------------ +// thread +//------------------------------------------------------------------------------ + +/// Information to pass to the new thread (what to run). +struct _thread_start_info { + void (*mFunction)(void *); ///< Pointer to the function to be executed. + void * mArg; ///< Function argument for the thread function. + thread * mThread; ///< Pointer to the thread object. +}; + +// Thread wrapper function. +#if defined(_TTHREAD_WIN32_) +unsigned WINAPI thread::wrapper_function(void * aArg) +#elif defined(_TTHREAD_POSIX_) +void * thread::wrapper_function(void * aArg) +#endif +{ + // Get thread startup information + _thread_start_info * ti = (_thread_start_info *) aArg; + + try + { + // Call the actual client thread function + ti->mFunction(ti->mArg); + } + catch(...) + { + // Uncaught exceptions will terminate the application (default behavior + // according to C++11) + std::terminate(); + } + + // The thread is no longer executing + lock_guard guard(ti->mThread->mDataMutex); + ti->mThread->mNotAThread = true; + + // The thread is responsible for freeing the startup information + delete ti; + + return 0; +} + +thread::thread(void (*aFunction)(void *), void * aArg) +{ + // Serialize access to this thread structure + lock_guard guard(mDataMutex); + + // Fill out the thread startup information (passed to the thread wrapper, + // which will eventually free it) + _thread_start_info * ti = new _thread_start_info; + ti->mFunction = aFunction; + ti->mArg = aArg; + ti->mThread = this; + + // The thread is now alive + mNotAThread = false; + + // Create the thread +#if defined(_TTHREAD_WIN32_) + mHandle = (HANDLE) _beginthreadex(0, 0, wrapper_function, (void *) ti, 0, &mWin32ThreadID); +#elif defined(_TTHREAD_POSIX_) + if(pthread_create(&mHandle, NULL, wrapper_function, (void *) ti) != 0) + mHandle = 0; +#endif + + // Did we fail to create the thread? + if(!mHandle) + { + mNotAThread = true; + delete ti; + } +} + +thread::~thread() +{ + if(joinable()) + std::terminate(); +} + +void thread::join() +{ + if(joinable()) + { +#if defined(_TTHREAD_WIN32_) + WaitForSingleObject(mHandle, INFINITE); + CloseHandle(mHandle); +#elif defined(_TTHREAD_POSIX_) + pthread_join(mHandle, NULL); +#endif + } +} + +bool thread::joinable() const +{ + mDataMutex.lock(); + bool result = !mNotAThread; + mDataMutex.unlock(); + return result; +} + +void thread::detach() +{ + mDataMutex.lock(); + if(!mNotAThread) + { +#if defined(_TTHREAD_WIN32_) + CloseHandle(mHandle); +#elif defined(_TTHREAD_POSIX_) + pthread_detach(mHandle); +#endif + mNotAThread = true; + } + mDataMutex.unlock(); +} + +thread::id thread::get_id() const +{ + if(!joinable()) + return id(); +#if defined(_TTHREAD_WIN32_) + return id((unsigned long int) mWin32ThreadID); +#elif defined(_TTHREAD_POSIX_) + return _pthread_t_to_ID(mHandle); +#endif +} + +unsigned thread::hardware_concurrency() +{ +#if defined(_TTHREAD_WIN32_) + SYSTEM_INFO si; + GetSystemInfo(&si); + return (int) si.dwNumberOfProcessors; +#elif defined(_SC_NPROCESSORS_ONLN) + return (int) sysconf(_SC_NPROCESSORS_ONLN); +#elif defined(_SC_NPROC_ONLN) + return (int) sysconf(_SC_NPROC_ONLN); +#else + // The standard requires this function to return zero if the number of + // hardware cores could not be determined. + return 0; +#endif +} + + +//------------------------------------------------------------------------------ +// this_thread +//------------------------------------------------------------------------------ + +thread::id this_thread::get_id() +{ +#if defined(_TTHREAD_WIN32_) + return thread::id((unsigned long int) GetCurrentThreadId()); +#elif defined(_TTHREAD_POSIX_) + return _pthread_t_to_ID(pthread_self()); +#endif +} + +} diff --git a/ext/tinythread.h b/ext/tinythread.h new file mode 100644 index 0000000000..956cf1d166 --- /dev/null +++ b/ext/tinythread.h @@ -0,0 +1,714 @@ +/* -*- mode: c++; tab-width: 2; indent-tabs-mode: nil; -*- +Copyright (c) 2010-2012 Marcus Geelnard + +This software is provided 'as-is', without any express or implied +warranty. In no event will the authors be held liable for any damages +arising from the use of this software. + +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it +freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + + 3. This notice may not be removed or altered from any source + distribution. +*/ + +#ifndef _TINYTHREAD_H_ +#define _TINYTHREAD_H_ + +/// @file +/// @mainpage TinyThread++ API Reference +/// +/// @section intro_sec Introduction +/// TinyThread++ is a minimal, portable implementation of basic threading +/// classes for C++. +/// +/// They closely mimic the functionality and naming of the C++11 standard, and +/// should be easily replaceable with the corresponding std:: variants. +/// +/// @section port_sec Portability +/// The Win32 variant uses the native Win32 API for implementing the thread +/// classes, while for other systems, the POSIX threads API (pthread) is used. +/// +/// @section class_sec Classes +/// In order to mimic the threading API of the C++11 standard, subsets of +/// several classes are provided. The fundamental classes are: +/// @li tthread::thread +/// @li tthread::mutex +/// @li tthread::recursive_mutex +/// @li tthread::condition_variable +/// @li tthread::lock_guard +/// @li tthread::fast_mutex +/// +/// @section misc_sec Miscellaneous +/// The following special keywords are available: #thread_local. +/// +/// For more detailed information (including additional classes), browse the +/// different sections of this documentation. A good place to start is: +/// tinythread.h. + +// Which platform are we on? +#if !defined(_TTHREAD_PLATFORM_DEFINED_) + #if defined(_WIN32) || defined(__WIN32__) || defined(__WINDOWS__) + #define _TTHREAD_WIN32_ + #else + #define _TTHREAD_POSIX_ + #endif + #define _TTHREAD_PLATFORM_DEFINED_ +#endif + +// Platform specific includes +#if defined(_TTHREAD_WIN32_) + #ifndef WIN32_LEAN_AND_MEAN + #define WIN32_LEAN_AND_MEAN + #define __UNDEF_LEAN_AND_MEAN + #endif + #include + #ifdef __UNDEF_LEAN_AND_MEAN + #undef WIN32_LEAN_AND_MEAN + #undef __UNDEF_LEAN_AND_MEAN + #endif +#else + #include + #include + #include + #include +#endif + +// Generic includes +#include + +/// TinyThread++ version (major number). +#define TINYTHREAD_VERSION_MAJOR 1 +/// TinyThread++ version (minor number). +#define TINYTHREAD_VERSION_MINOR 1 +/// TinyThread++ version (full version). +#define TINYTHREAD_VERSION (TINYTHREAD_VERSION_MAJOR * 100 + TINYTHREAD_VERSION_MINOR) + +// Do we have a fully featured C++11 compiler? +#if (__cplusplus > 199711L) || (defined(__STDCXX_VERSION__) && (__STDCXX_VERSION__ >= 201001L)) + #define _TTHREAD_CPP11_ +#endif + +// ...at least partial C++11? +#if defined(_TTHREAD_CPP11_) || defined(__GXX_EXPERIMENTAL_CXX0X__) || defined(__GXX_EXPERIMENTAL_CPP0X__) + #define _TTHREAD_CPP11_PARTIAL_ +#endif + +// Macro for disabling assignments of objects. +#ifdef _TTHREAD_CPP11_PARTIAL_ + #define _TTHREAD_DISABLE_ASSIGNMENT(name) \ + name(const name&) = delete; \ + name& operator=(const name&) = delete; +#else + #define _TTHREAD_DISABLE_ASSIGNMENT(name) \ + name(const name&); \ + name& operator=(const name&); +#endif + +/// @def thread_local +/// Thread local storage keyword. +/// A variable that is declared with the @c thread_local keyword makes the +/// value of the variable local to each thread (known as thread-local storage, +/// or TLS). Example usage: +/// @code +/// // This variable is local to each thread. +/// thread_local int variable; +/// @endcode +/// @note The @c thread_local keyword is a macro that maps to the corresponding +/// compiler directive (e.g. @c __declspec(thread)). While the C++11 standard +/// allows for non-trivial types (e.g. classes with constructors and +/// destructors) to be declared with the @c thread_local keyword, most pre-C++11 +/// compilers only allow for trivial types (e.g. @c int). So, to guarantee +/// portable code, only use trivial types for thread local storage. +/// @note This directive is currently not supported on Mac OS X (it will give +/// a compiler error), since compile-time TLS is not supported in the Mac OS X +/// executable format. Also, some older versions of MinGW (before GCC 4.x) do +/// not support this directive. +/// @hideinitializer + +#if !defined(_TTHREAD_CPP11_) && !defined(thread_local) + #if defined(__GNUC__) || defined(__INTEL_COMPILER) || defined(__SUNPRO_CC) || defined(__IBMCPP__) + #define thread_local __thread + #else + #define thread_local __declspec(thread) + #endif +#endif + + +/// Main name space for TinyThread++. +/// This namespace is more or less equivalent to the @c std namespace for the +/// C++11 thread classes. For instance, the tthread::mutex class corresponds to +/// the std::mutex class. +namespace tthread { + +/// Mutex class. +/// This is a mutual exclusion object for synchronizing access to shared +/// memory areas for several threads. The mutex is non-recursive (i.e. a +/// program may deadlock if the thread that owns a mutex object calls lock() +/// on that object). +/// @see recursive_mutex +class mutex { + public: + /// Constructor. + mutex() +#if defined(_TTHREAD_WIN32_) + : mAlreadyLocked(false) +#endif + { +#if defined(_TTHREAD_WIN32_) + InitializeCriticalSection(&mHandle); +#else + pthread_mutex_init(&mHandle, NULL); +#endif + } + + /// Destructor. + ~mutex() + { +#if defined(_TTHREAD_WIN32_) + DeleteCriticalSection(&mHandle); +#else + pthread_mutex_destroy(&mHandle); +#endif + } + + /// Lock the mutex. + /// The method will block the calling thread until a lock on the mutex can + /// be obtained. The mutex remains locked until @c unlock() is called. + /// @see lock_guard + inline void lock() + { +#if defined(_TTHREAD_WIN32_) + EnterCriticalSection(&mHandle); + while(mAlreadyLocked) Sleep(1000); // Simulate deadlock... + mAlreadyLocked = true; +#else + pthread_mutex_lock(&mHandle); +#endif + } + + /// Try to lock the mutex. + /// The method will try to lock the mutex. If it fails, the function will + /// return immediately (non-blocking). + /// @return @c true if the lock was acquired, or @c false if the lock could + /// not be acquired. + inline bool try_lock() + { +#if defined(_TTHREAD_WIN32_) + bool ret = (TryEnterCriticalSection(&mHandle) ? true : false); + if(ret && mAlreadyLocked) + { + LeaveCriticalSection(&mHandle); + ret = false; + } + return ret; +#else + return (pthread_mutex_trylock(&mHandle) == 0) ? true : false; +#endif + } + + /// Unlock the mutex. + /// If any threads are waiting for the lock on this mutex, one of them will + /// be unblocked. + inline void unlock() + { +#if defined(_TTHREAD_WIN32_) + mAlreadyLocked = false; + LeaveCriticalSection(&mHandle); +#else + pthread_mutex_unlock(&mHandle); +#endif + } + + _TTHREAD_DISABLE_ASSIGNMENT(mutex) + + private: +#if defined(_TTHREAD_WIN32_) + CRITICAL_SECTION mHandle; + bool mAlreadyLocked; +#else + pthread_mutex_t mHandle; +#endif + + friend class condition_variable; +}; + +/// Recursive mutex class. +/// This is a mutual exclusion object for synchronizing access to shared +/// memory areas for several threads. The mutex is recursive (i.e. a thread +/// may lock the mutex several times, as long as it unlocks the mutex the same +/// number of times). +/// @see mutex +class recursive_mutex { + public: + /// Constructor. + recursive_mutex() + { +#if defined(_TTHREAD_WIN32_) + InitializeCriticalSection(&mHandle); +#else + pthread_mutexattr_t attr; + pthread_mutexattr_init(&attr); + pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); + pthread_mutex_init(&mHandle, &attr); +#endif + } + + /// Destructor. + ~recursive_mutex() + { +#if defined(_TTHREAD_WIN32_) + DeleteCriticalSection(&mHandle); +#else + pthread_mutex_destroy(&mHandle); +#endif + } + + /// Lock the mutex. + /// The method will block the calling thread until a lock on the mutex can + /// be obtained. The mutex remains locked until @c unlock() is called. + /// @see lock_guard + inline void lock() + { +#if defined(_TTHREAD_WIN32_) + EnterCriticalSection(&mHandle); +#else + pthread_mutex_lock(&mHandle); +#endif + } + + /// Try to lock the mutex. + /// The method will try to lock the mutex. If it fails, the function will + /// return immediately (non-blocking). + /// @return @c true if the lock was acquired, or @c false if the lock could + /// not be acquired. + inline bool try_lock() + { +#if defined(_TTHREAD_WIN32_) + return TryEnterCriticalSection(&mHandle) ? true : false; +#else + return (pthread_mutex_trylock(&mHandle) == 0) ? true : false; +#endif + } + + /// Unlock the mutex. + /// If any threads are waiting for the lock on this mutex, one of them will + /// be unblocked. + inline void unlock() + { +#if defined(_TTHREAD_WIN32_) + LeaveCriticalSection(&mHandle); +#else + pthread_mutex_unlock(&mHandle); +#endif + } + + _TTHREAD_DISABLE_ASSIGNMENT(recursive_mutex) + + private: +#if defined(_TTHREAD_WIN32_) + CRITICAL_SECTION mHandle; +#else + pthread_mutex_t mHandle; +#endif + + friend class condition_variable; +}; + +/// Lock guard class. +/// The constructor locks the mutex, and the destructor unlocks the mutex, so +/// the mutex will automatically be unlocked when the lock guard goes out of +/// scope. Example usage: +/// @code +/// mutex m; +/// int counter; +/// +/// void increment() +/// { +/// lock_guard guard(m); +/// ++ counter; +/// } +/// @endcode + +template +class lock_guard { + public: + typedef T mutex_type; + + lock_guard() : mMutex(0) {} + + /// The constructor locks the mutex. + explicit lock_guard(mutex_type &aMutex) + { + mMutex = &aMutex; + mMutex->lock(); + } + + /// The destructor unlocks the mutex. + ~lock_guard() + { + if(mMutex) + mMutex->unlock(); + } + + private: + mutex_type * mMutex; +}; + +/// Condition variable class. +/// This is a signalling object for synchronizing the execution flow for +/// several threads. Example usage: +/// @code +/// // Shared data and associated mutex and condition variable objects +/// int count; +/// mutex m; +/// condition_variable cond; +/// +/// // Wait for the counter to reach a certain number +/// void wait_counter(int targetCount) +/// { +/// lock_guard guard(m); +/// while(count < targetCount) +/// cond.wait(m); +/// } +/// +/// // Increment the counter, and notify waiting threads +/// void increment() +/// { +/// lock_guard guard(m); +/// ++ count; +/// cond.notify_all(); +/// } +/// @endcode +class condition_variable { + public: + /// Constructor. +#if defined(_TTHREAD_WIN32_) + condition_variable(); +#else + condition_variable() + { + pthread_cond_init(&mHandle, NULL); + } +#endif + + /// Destructor. +#if defined(_TTHREAD_WIN32_) + ~condition_variable(); +#else + ~condition_variable() + { + pthread_cond_destroy(&mHandle); + } +#endif + + /// Wait for the condition. + /// The function will block the calling thread until the condition variable + /// is woken by @c notify_one(), @c notify_all() or a spurious wake up. + /// @param[in] aMutex A mutex that will be unlocked when the wait operation + /// starts, an locked again as soon as the wait operation is finished. + template + inline void wait(_mutexT &aMutex) + { +#if defined(_TTHREAD_WIN32_) + // Increment number of waiters + EnterCriticalSection(&mWaitersCountLock); + ++ mWaitersCount; + LeaveCriticalSection(&mWaitersCountLock); + + // Release the mutex while waiting for the condition (will decrease + // the number of waiters when done)... + aMutex.unlock(); + _wait(); + aMutex.lock(); +#else + pthread_cond_wait(&mHandle, &aMutex.mHandle); +#endif + } + + /// Notify one thread that is waiting for the condition. + /// If at least one thread is blocked waiting for this condition variable, + /// one will be woken up. + /// @note Only threads that started waiting prior to this call will be + /// woken up. +#if defined(_TTHREAD_WIN32_) + void notify_one(); +#else + inline void notify_one() + { + pthread_cond_signal(&mHandle); + } +#endif + + /// Notify all threads that are waiting for the condition. + /// All threads that are blocked waiting for this condition variable will + /// be woken up. + /// @note Only threads that started waiting prior to this call will be + /// woken up. +#if defined(_TTHREAD_WIN32_) + void notify_all(); +#else + inline void notify_all() + { + pthread_cond_broadcast(&mHandle); + } +#endif + + _TTHREAD_DISABLE_ASSIGNMENT(condition_variable) + + private: +#if defined(_TTHREAD_WIN32_) + void _wait(); + HANDLE mEvents[2]; ///< Signal and broadcast event HANDLEs. + unsigned int mWaitersCount; ///< Count of the number of waiters. + CRITICAL_SECTION mWaitersCountLock; ///< Serialize access to mWaitersCount. +#else + pthread_cond_t mHandle; +#endif +}; + + +/// Thread class. +class thread { + public: +#if defined(_TTHREAD_WIN32_) + typedef HANDLE native_handle_type; +#else + typedef pthread_t native_handle_type; +#endif + + class id; + + /// Default constructor. + /// Construct a @c thread object without an associated thread of execution + /// (i.e. non-joinable). + thread() : mHandle(0), mNotAThread(true) +#if defined(_TTHREAD_WIN32_) + , mWin32ThreadID(0) +#endif + {} + + /// Thread starting constructor. + /// Construct a @c thread object with a new thread of execution. + /// @param[in] aFunction A function pointer to a function of type: + /// void fun(void * arg) + /// @param[in] aArg Argument to the thread function. + /// @note This constructor is not fully compatible with the standard C++ + /// thread class. It is more similar to the pthread_create() (POSIX) and + /// CreateThread() (Windows) functions. + thread(void (*aFunction)(void *), void * aArg); + + /// Destructor. + /// @note If the thread is joinable upon destruction, @c std::terminate() + /// will be called, which terminates the process. It is always wise to do + /// @c join() before deleting a thread object. + ~thread(); + + /// Wait for the thread to finish (join execution flows). + /// After calling @c join(), the thread object is no longer associated with + /// a thread of execution (i.e. it is not joinable, and you may not join + /// with it nor detach from it). + void join(); + + /// Check if the thread is joinable. + /// A thread object is joinable if it has an associated thread of execution. + bool joinable() const; + + /// Detach from the thread. + /// After calling @c detach(), the thread object is no longer assicated with + /// a thread of execution (i.e. it is not joinable). The thread continues + /// execution without the calling thread blocking, and when the thread + /// ends execution, any owned resources are released. + void detach(); + + /// Return the thread ID of a thread object. + id get_id() const; + + /// Get the native handle for this thread. + /// @note Under Windows, this is a @c HANDLE, and under POSIX systems, this + /// is a @c pthread_t. + inline native_handle_type native_handle() + { + return mHandle; + } + + /// Determine the number of threads which can possibly execute concurrently. + /// This function is useful for determining the optimal number of threads to + /// use for a task. + /// @return The number of hardware thread contexts in the system. + /// @note If this value is not defined, the function returns zero (0). + static unsigned hardware_concurrency(); + + _TTHREAD_DISABLE_ASSIGNMENT(thread) + + private: + native_handle_type mHandle; ///< Thread handle. + mutable mutex mDataMutex; ///< Serializer for access to the thread private data. + bool mNotAThread; ///< True if this object is not a thread of execution. +#if defined(_TTHREAD_WIN32_) + unsigned int mWin32ThreadID; ///< Unique thread ID (filled out by _beginthreadex). +#endif + + // This is the internal thread wrapper function. +#if defined(_TTHREAD_WIN32_) + static unsigned WINAPI wrapper_function(void * aArg); +#else + static void * wrapper_function(void * aArg); +#endif +}; + +/// Thread ID. +/// The thread ID is a unique identifier for each thread. +/// @see thread::get_id() +class thread::id { + public: + /// Default constructor. + /// The default constructed ID is that of thread without a thread of + /// execution. + id() : mId(0) {}; + + id(unsigned long int aId) : mId(aId) {}; + + id(const id& aId) : mId(aId.mId) {}; + + inline id & operator=(const id &aId) + { + mId = aId.mId; + return *this; + } + + inline friend bool operator==(const id &aId1, const id &aId2) + { + return (aId1.mId == aId2.mId); + } + + inline friend bool operator!=(const id &aId1, const id &aId2) + { + return (aId1.mId != aId2.mId); + } + + inline friend bool operator<=(const id &aId1, const id &aId2) + { + return (aId1.mId <= aId2.mId); + } + + inline friend bool operator<(const id &aId1, const id &aId2) + { + return (aId1.mId < aId2.mId); + } + + inline friend bool operator>=(const id &aId1, const id &aId2) + { + return (aId1.mId >= aId2.mId); + } + + inline friend bool operator>(const id &aId1, const id &aId2) + { + return (aId1.mId > aId2.mId); + } + + inline friend std::ostream& operator <<(std::ostream &os, const id &obj) + { + os << obj.mId; + return os; + } + + private: + unsigned long int mId; +}; + + +// Related to - minimal to be able to support chrono. +typedef long long __intmax_t; + +/// Minimal implementation of the @c ratio class. This class provides enough +/// functionality to implement some basic @c chrono classes. +template <__intmax_t N, __intmax_t D = 1> class ratio { + public: + static double _as_double() { return double(N) / double(D); } +}; + +/// Minimal implementation of the @c chrono namespace. +/// The @c chrono namespace provides types for specifying time intervals. +namespace chrono { + /// Duration template class. This class provides enough functionality to + /// implement @c this_thread::sleep_for(). + template > class duration { + private: + _Rep rep_; + public: + typedef _Rep rep; + typedef _Period period; + + /// Construct a duration object with the given duration. + template + explicit duration(const _Rep2& r) : rep_(r) {}; + + /// Return the value of the duration object. + rep count() const + { + return rep_; + } + }; + + // Standard duration types. + typedef duration<__intmax_t, ratio<1, 1000000000> > nanoseconds; ///< Duration with the unit nanoseconds. + typedef duration<__intmax_t, ratio<1, 1000000> > microseconds; ///< Duration with the unit microseconds. + typedef duration<__intmax_t, ratio<1, 1000> > milliseconds; ///< Duration with the unit milliseconds. + typedef duration<__intmax_t> seconds; ///< Duration with the unit seconds. + typedef duration<__intmax_t, ratio<60> > minutes; ///< Duration with the unit minutes. + typedef duration<__intmax_t, ratio<3600> > hours; ///< Duration with the unit hours. +} + +/// The namespace @c this_thread provides methods for dealing with the +/// calling thread. +namespace this_thread { + /// Return the thread ID of the calling thread. + thread::id get_id(); + + /// Yield execution to another thread. + /// Offers the operating system the opportunity to schedule another thread + /// that is ready to run on the current processor. + inline void yield() + { +#if defined(_TTHREAD_WIN32_) + Sleep(0); +#else + sched_yield(); +#endif + } + + /// Blocks the calling thread for a period of time. + /// @param[in] aTime Minimum time to put the thread to sleep. + /// Example usage: + /// @code + /// // Sleep for 100 milliseconds + /// this_thread::sleep_for(chrono::milliseconds(100)); + /// @endcode + /// @note Supported duration types are: nanoseconds, microseconds, + /// milliseconds, seconds, minutes and hours. + template void sleep_for(const chrono::duration<_Rep, _Period>& aTime) + { +#if defined(_TTHREAD_WIN32_) + Sleep(int(double(aTime.count()) * (1000.0 * _Period::_as_double()) + 0.5)); +#else + usleep(int(double(aTime.count()) * (1000000.0 * _Period::_as_double()) + 0.5)); +#endif + } +} + +} + +// Define/macro cleanup +#undef _TTHREAD_DISABLE_ASSIGNMENT + +#endif // _TINYTHREAD_H_ diff --git a/scripts/defaultSettings.cfg b/scripts/defaultSettings.cfg new file mode 100644 index 0000000000..d93b7d07f8 --- /dev/null +++ b/scripts/defaultSettings.cfg @@ -0,0 +1,4 @@ +{ + BasePathOffset = "../../.." + +} \ No newline at end of file diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 80cbb421b4..abe892d01a 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -85,5 +85,8 @@ source_group(Util FILES ${UTIL_SOURCE} ${UTIL_HEADER}) include_directories(${HEADER_ROOT_DIR}) +# hack: +set(OPENSPACE_SOURCE ${OPENSPACE_SOURCE} ${OPENSPACE_EXT_DIR}/tinythread.cpp) + add_executable(OpenSpace ${OPENSPACE_HEADER} ${OPENSPACE_SOURCE}) target_link_libraries(OpenSpace ${DEPENDENT_LIBS}) diff --git a/src/interaction/deviceidentifier.cpp b/src/interaction/deviceidentifier.cpp index ecac780d05..f7a1e5ba7c 100644 --- a/src/interaction/deviceidentifier.cpp +++ b/src/interaction/deviceidentifier.cpp @@ -3,7 +3,9 @@ #include "deviceIdentifier.h" // sgct includes -#include "sgct.h" +//#include "sgct.h" + +#include namespace openspace { @@ -57,16 +59,17 @@ void DeviceIdentifier::scanDevices() { for (int i = 0; i < MAXDEVICES; ++i) { // check for device on position i - const char* joystickName = sgct::Engine::getJoystickName(SGCT_JOYSTICK_1 + i); + // const char* joystickName = sgct::Engine::getJoystickName(SGCT_JOYSTICK_1 + i); // int joystickPresent = sgct::Engine::getJoystickParam( GLFW_JOYSTICK_1 + i, GLFW_PRESENT ); //numberOfAxes_[i] = sgct::Engine::getJoystickParam( GLFW_JOYSTICK_1 + i, GLFW_AXES ); //numberOfButtons_[i] = sgct::Engine::getJoystickParam( GLFW_JOYSTICK_1 + i, GLFW_BUTTONS ); // joystick found + void* joystickName; if( joystickName != NULL ) { - sgct::Engine::getJoystickAxes(SGCT_JOYSTICK_1 + i, &numberOfAxes_[i]); - sgct::Engine::getJoystickButtons(SGCT_JOYSTICK_1 + i, &numberOfButtons_[i]); +// sgct::Engine::getJoystickAxes(SGCT_JOYSTICK_1 + i, &numberOfAxes_[i]); +// sgct::Engine::getJoystickButtons(SGCT_JOYSTICK_1 + i, &numberOfButtons_[i]); @@ -118,10 +121,10 @@ void DeviceIdentifier::update() { void DeviceIdentifier::update(const int device) { assert(this_); if(inputDevice_[device] != InputDevice::NONE) { - const float* axesPos = sgct::Engine::getJoystickAxes(GLFW_JOYSTICK_1+device, &(numberOfAxes_[device]) ); + // const float* axesPos = sgct::Engine::getJoystickAxes(GLFW_JOYSTICK_1+device, &(numberOfAxes_[device]) ); //axesPos_[device] - const unsigned char* buttons = sgct::Engine::getJoystickButtons( GLFW_JOYSTICK_1+device, &(numberOfButtons_[device]) ); + //const unsigned char* buttons = sgct::Engine::getJoystickButtons( GLFW_JOYSTICK_1+device, &(numberOfButtons_[device]) ); //buttons_[device] } } diff --git a/src/interaction/externalcontrol/externalcontrol.h b/src/interaction/externalcontrol/externalcontrol.h index 8b270bad7f..6b12c3c75c 100644 --- a/src/interaction/externalcontrol/externalcontrol.h +++ b/src/interaction/externalcontrol/externalcontrol.h @@ -12,7 +12,7 @@ public: // constructors & destructor ExternalControl(); - ~ExternalControl(); + virtual ~ExternalControl(); virtual void update(); diff --git a/src/interaction/externalcontrol/randomexternalcontrol.h b/src/interaction/externalcontrol/randomexternalcontrol.h index 6b5347b320..a552ff54ba 100644 --- a/src/interaction/externalcontrol/randomexternalcontrol.h +++ b/src/interaction/externalcontrol/randomexternalcontrol.h @@ -18,7 +18,7 @@ public: private: std::mutex inputGuard; bool *keepGoing_; - std::thread *backgroundThread; + // std::thread *backgroundThread; }; } // namespace openspace diff --git a/src/main.cpp b/src/main.cpp index 2428d89658..fe48453136 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,3 +1,27 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014 * + * * + * 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. * + ****************************************************************************************/ + // open space includes #include "openspaceengine.h" @@ -5,20 +29,7 @@ // sgct includes #include "sgct.h" -// std includes -#include -#include - -#include - -#include -#include -#include -#include - -// graphics and openspace engines -sgct::Engine * gEngine; -openspace::OpenSpaceEngine* rEngine; +sgct::Engine* _sgctEngine; // function pointer declarations void mainInitFunc(void); @@ -33,158 +44,26 @@ void mainMouseScrollCallback(double posX, double posY); void mainEncodeFun(); void mainDecodeFun(); -void PrintTable(lua_State *L) -{ - lua_pushnil(L); - - while(lua_next(L, -2) != 0) - { - if(lua_isstring(L, -1)) - printf("%s = %s\n", lua_tostring(L, -2), lua_tostring(L, -1)); - else if(lua_isnumber(L, -1)) - printf("%s = %d\n", lua_tostring(L, -2), lua_tonumber(L, -1)); - else if(lua_istable(L, -1)) - PrintTable(L); - - lua_pop(L, 1); - } -} - -static void stackDump (lua_State *L) { - int i; - int top = lua_gettop(L); - for (i = 1; i <= top; i++) { /* repeat for each level */ - int t = lua_type(L, i); - switch (t) { - - case LUA_TSTRING: /* strings */ - printf("`%s'", lua_tostring(L, i)); - break; - - case LUA_TBOOLEAN: /* booleans */ - printf(lua_toboolean(L, i) ? "true" : "false"); - break; - - case LUA_TNUMBER: /* numbers */ - printf("%g", lua_tonumber(L, i)); - break; - - case LUA_TTABLE: - PrintTable(L); - break; - default: /* other values */ - printf("%s", lua_typename(L, t)); - break; - - } - printf(" "); /* put a separator */ - } - printf("\n"); /* end the listing */ -} - int main(int argc, char **argv) { -#if 0 - LARGE_INTEGER t1; - QueryPerformanceCounter(&t1); - lua_State* l = luaL_newstate(); - LARGE_INTEGER t2; - QueryPerformanceCounter(&t2); - - luaL_openlibs(l); - LARGE_INTEGER t3; - QueryPerformanceCounter(&t3); - - //std::ifstream file("../../scripts/script.lua"); - //int length; - //file.seekg(0, std::ios::end); // go to the end - //length = file.tellg(); // report location (this is the length) - //file.seekg(0, std::ios::beg); // go back to the beginning - //char* buffer = new char[length]; // allocate memory for a buffer of appropriate dimension - //file.read(buffer, length); // read the whole file into the buffer - //file.close(); - - //if (luaL_loadstring(l, buffer)) { - if (luaL_loadfile(l, "../../scripts/script.lua")) { - std::cerr << lua_tostring(l, -1) << std::endl; - return EXIT_SUCCESS; - } - LARGE_INTEGER t4; - QueryPerformanceCounter(&t4); - - if (lua_pcall(l,0, LUA_MULTRET, 0)) { - std::cerr << lua_tostring(l, -1) << std::endl; - return EXIT_SUCCESS; - } - LARGE_INTEGER t5; - QueryPerformanceCounter(&t5); - - //stackDump(l); - - lua_getglobal(l, "config"); - std::cout << "Table|Function|NIL|bool|thread|none|noneornil" << std::endl; - std::cout << lua_istable(l, -1) << "|" << - lua_isfunction(l, -1) << "|" << - lua_isnil(l, -1) << "|" << - lua_isboolean(l, -1) << "|" << - lua_isthread(l, -1) << "|" << - lua_isnone(l, -1) << "|" << - lua_isnoneornil(l, -1) << "|" << - std::endl; - - stackDump(l); - - - - lua_close(l); - LARGE_INTEGER t6; - QueryPerformanceCounter(&t6); - - - - - // -------- - LARGE_INTEGER freq; - QueryPerformanceFrequency(&freq); - - std::cout << "State: " << ((t2.QuadPart - t1.QuadPart) / double(freq.QuadPart)) * 1000 << std::endl; - std::cout << "Libs : " << ((t3.QuadPart - t2.QuadPart) / double(freq.QuadPart)) * 1000 << std::endl; - std::cout << "Load : " << ((t4.QuadPart - t3.QuadPart) / double(freq.QuadPart)) * 1000 << std::endl; - std::cout << "Exec : " << ((t5.QuadPart - t4.QuadPart) / double(freq.QuadPart)) * 1000 << std::endl; - std::cout << "Close: " << ((t6.QuadPart - t5.QuadPart) / double(freq.QuadPart)) * 1000 << std::endl; + int newArgc; + char** newArgv; + openspace::OpenSpaceEngine::create(argc, argv, newArgc, newArgv); - exit(EXIT_SUCCESS); - -#endif - - openspace::OpenSpaceEngine::create(argc, argv); - - char* cmd = "-config"; - const std::string pathStr = absPath("${BASE_PATH}/config/single.xml"); - char* path = _strdup(pathStr.c_str()); - char** newArgv = new char*[3]; - int newArgc = 3; - newArgv[0] = argv[0]; - newArgv[1] = cmd; - newArgv[2] = path; - - - // allocate sgct- and openspace engine objects - gEngine = new sgct::Engine( newArgc, newArgv ); + _sgctEngine = new sgct::Engine(newArgc, newArgv); - free(path); delete[] newArgv; // Bind functions - gEngine->setInitOGLFunction( mainInitFunc ); - gEngine->setPreSyncFunction( mainPreSyncFunc ); - gEngine->setPostSyncPreDrawFunction( mainPostSyncPreDrawFunc ); - gEngine->setDrawFunction( mainRenderFunc ); - gEngine->setPostDrawFunction( mainPostDrawFunc ); - gEngine->setKeyboardCallbackFunction( mainKeyboardCallback ); - gEngine->setMouseButtonCallbackFunction( mainMouseButtonCallback ); - gEngine->setMousePosCallbackFunction( mainMousePosCallback ); - gEngine->setMouseScrollCallbackFunction( mainMouseScrollCallback ); + _sgctEngine->setInitOGLFunction( mainInitFunc ); + _sgctEngine->setPreSyncFunction( mainPreSyncFunc ); + _sgctEngine->setPostSyncPreDrawFunction( mainPostSyncPreDrawFunc ); + _sgctEngine->setDrawFunction( mainRenderFunc ); + _sgctEngine->setPostDrawFunction( mainPostDrawFunc ); + _sgctEngine->setKeyboardCallbackFunction( mainKeyboardCallback ); + _sgctEngine->setMouseButtonCallbackFunction( mainMouseButtonCallback ); + _sgctEngine->setMousePosCallbackFunction( mainMousePosCallback ); + _sgctEngine->setMouseScrollCallbackFunction( mainMouseScrollCallback ); // set encode and decode functions // NOTE: starts synchronizing before init functions @@ -192,18 +71,18 @@ int main(int argc, char **argv) { sgct::SharedData::instance()->setDecodeFunction(mainDecodeFun); // try to open a window - if( ! gEngine->init(sgct::Engine::OpenGL_4_0_Core_Profile)) { + if( ! _sgctEngine->init(sgct::Engine::OpenGL_4_0_Core_Profile)) { // could not open a window, deallocates and exits - delete gEngine; + delete _sgctEngine; openspace::OpenSpaceEngine::destroy(); return EXIT_FAILURE; } // Main loop - gEngine->render(); + _sgctEngine->render(); // Clean up (de-allocate) - delete gEngine; + delete _sgctEngine; // Exit program exit( EXIT_SUCCESS ); @@ -232,24 +111,24 @@ void mainPostDrawFunc(void) { } void mainKeyboardCallback(int key, int action) { - if (gEngine->isMaster()) + if (_sgctEngine->isMaster()) OsEng.keyboardCallback(key, action); } void mainMouseButtonCallback(int key, int action) { - if (gEngine->isMaster()) + if (_sgctEngine->isMaster()) OsEng.mouseButtonCallback(key, action); } void mainMousePosCallback(double x, double y) { // TODO use float instead - if (gEngine->isMaster()) + if (_sgctEngine->isMaster()) OsEng.mousePositionCallback(static_cast(x), static_cast(y)); } void mainMouseScrollCallback(double pos, double /*pos2*/) { // TODO use float instead - if (gEngine->isMaster()) + if (_sgctEngine->isMaster()) OsEng.mouseScrollWheelCallback(static_cast(pos)); } diff --git a/src/openspaceengine.cpp b/src/openspaceengine.cpp index fbc6a8aed0..0810c4c9e5 100644 --- a/src/openspaceengine.cpp +++ b/src/openspaceengine.cpp @@ -73,24 +73,34 @@ OpenSpaceEngine& OpenSpaceEngine::ref() { return *_engine; } -void OpenSpaceEngine::create(int& argc, char**& argv) { - // TODO add parsing of configuration file, configuration file loading - LogManager::initialize(LogManager::LogLevel::Debug); - LogMgr.addLog(new ConsoleLog); - - ghoul::filesystem::FileSystem::initialize(); - //FileSys.registerPathToken("${BASE_PATH}", "../../.."); - FileSys.registerPathToken("${BASE_PATH}", "../.."); - FileSys.registerPathToken("${SCRIPTS}", "${BASE_PATH}/scripts"); - +void OpenSpaceEngine::create(int argc, char** argv, int& newArgc, char**& newArgv) { // TODO custom assert (ticket #5) assert(_engine == nullptr); _engine = new OpenSpaceEngine; + + LogManager::initialize(LogManager::LogLevel::Debug); + LogMgr.addLog(new ConsoleLog); + + _engine->_configurationManager = new ghoul::ConfigurationManager; + _engine->_configurationManager->initialize(); + + newArgc = 3; + newArgv = new char*[3]; + newArgv[0] = "prog"; + newArgv[1] = "-config"; + newArgv[2] = "../../../config/single.xml"; + + + + ghoul::filesystem::FileSystem::initialize(); + FileSys.registerPathToken("${BASE_PATH}", "../../.."); + //FileSys.registerPathToken("${BASE_PATH}", "../.."); + FileSys.registerPathToken("${SCRIPTS}", "${BASE_PATH}/scripts"); + _engine->_renderEngine = new RenderEngine; _engine->_interactionHandler = new InteractionHandler; - _engine->_configurationManager = new ghoul::ConfigurationManager; } void OpenSpaceEngine::destroy() { @@ -102,93 +112,6 @@ bool OpenSpaceEngine::initialize() { _configurationManager->loadConfiguration("${SCRIPTS}/config.lua"); _configurationManager->loadConfiguration("${SCRIPTS}/config2.lua"); - LARGE_INTEGER freq; - QueryPerformanceFrequency(&freq); - - //ghoul::lua::lua_logStack(_configurationManager->_state); - // - //lua_getglobal(_configurationManager->_state, "printTable"); - //lua_getglobal(_configurationManager->_state, "config"); - //lua_pcall(_configurationManager->_state, 1, 0, NULL); - - int s = 0; - char t = 0; - long long u = 0; - unsigned long d = 0; - _configurationManager->setValue("key", s); - _configurationManager->setValue("key", t); - _configurationManager->setValue("key", u); - _configurationManager->setValue("key", d); - - //LINFO("All Keys:"); - //std::vector keys = _configurationManager->keys(); - //for (const std::string& k : keys) { - // LINFO(k); - //} - - - LINFO("Keys (t):"); - std::vector keys = _configurationManager->keys("tt.t"); - for (const std::string& k : keys) { - LINFO(k); - } - - - //LINFO("setting2"); - //_configurationManager->setValue("setting2", 5); - - //lua_getglobal(_configurationManager->_state, "printTable"); - //lua_getglobal(_configurationManager->_state, "config"); - //lua_pcall(_configurationManager->_state, 1, 0, NULL); - - //LINFO("t.s"); - //_configurationManager->setValue("t.s", 10); - - //lua_getglobal(_configurationManager->_state, "printTable"); - //lua_getglobal(_configurationManager->_state, "config"); - //lua_pcall(_configurationManager->_state, 1, 0, NULL); - - //LINFO("table.te.s.foo"); - //_configurationManager->setValue("table.te.s.foo", 12); - - //lua_getglobal(_configurationManager->_state, "printTable"); - //lua_getglobal(_configurationManager->_state, "config"); - //lua_pcall(_configurationManager->_state, 1, 0, NULL); - - - //int v; - //LINFO("setting2"); - //LARGE_INTEGER t1, t2; - //QueryPerformanceCounter(&t1); - //bool success = _configurationManager->getValue("setting2", v); - //QueryPerformanceCounter(&t2); - //LINFO("Get: " << ((t2.QuadPart - t1.QuadPart) / double(freq.QuadPart)) * 1000* 1000); - //LINFO("Value:" << v); - //QueryPerformanceCounter(&t1); - //_configurationManager->setValue("setting2", 5); - //QueryPerformanceCounter(&t2); - //LINFO("Set: " << ((t2.QuadPart - t1.QuadPart) / double(freq.QuadPart)) * 1000* 1000); - //success = _configurationManager->getValue("setting2", v); - //LINFO("Value:" << v); - - ////_configurationManager->setValue("setting2", 5); - //ghoul::lua::lua_logStack(_configurationManager->_state); - ////success = _configurationManager->getValue("setting2", v); - - //LINFO("t.s"); - //QueryPerformanceCounter(&t1); - //success = _configurationManager->getValue("t.s", v); - //QueryPerformanceCounter(&t2); - //LINFO(((t2.QuadPart - t1.QuadPart) / double(freq.QuadPart)) * 1000 * 1000); - //ghoul::lua::lua_logStack(_configurationManager->_state); - - //LINFO("table.te.s.foo"); - //QueryPerformanceCounter(&t1); - //success = _configurationManager->getValue("table.te.s.foo", v); - //QueryPerformanceCounter(&t2); - //LINFO(((t2.QuadPart - t1.QuadPart) / double(freq.QuadPart)) * 1000 * 1000); - //ghoul::lua::lua_logStack(_configurationManager->_state); - Time::init(); Spice::init(); Spice::ref().loadDefaultKernels(); diff --git a/src/openspaceengine.h b/src/openspaceengine.h index cf52cade3b..3c69556ed2 100644 --- a/src/openspaceengine.h +++ b/src/openspaceengine.h @@ -35,7 +35,7 @@ class ScriptEngine; class OpenSpaceEngine { public: - static void create(int& argc, char**& argv); + static void create(int argc, char** argv, int& newArgc, char**& newArgv); static void destroy(); static OpenSpaceEngine& ref(); diff --git a/src/rendering/renderableplanet.h b/src/rendering/renderableplanet.h index 70547af11a..5bf689788d 100644 --- a/src/rendering/renderableplanet.h +++ b/src/rendering/renderableplanet.h @@ -27,7 +27,7 @@ public: private: ghoul::opengl::ProgramObject *programObject_; ghoul::opengl::Texture *texture_; - double rad_; + // double rad_; Planet *planet_; }; diff --git a/src/scenegraph/scenegraph.cpp b/src/scenegraph/scenegraph.cpp index 59e5580578..69e45291d0 100644 --- a/src/scenegraph/scenegraph.cpp +++ b/src/scenegraph/scenegraph.cpp @@ -39,10 +39,10 @@ void SceneGraph::init() { // logger string std::string _loggerCat = "SceneGraph::init"; - SceneGraphLoader *loader = new SceneGraphLoader(&nodes_, &shaders_); - root_ = loader->loadSceneGraph(absPath("${BASE_PATH}/modules")); + // SceneGraphLoader *loader = new SceneGraphLoader(&nodes_, &shaders_); + // root_ = loader->loadSceneGraph(absPath("${BASE_PATH}/modules")); update(); - pss bs = root_->calculateBoundingSphere(); + //pss bs = root_->calculateBoundingSphere(); } void SceneGraph::update() { diff --git a/src/scenegraph/scenegraphloader.cpp b/src/scenegraph/scenegraphloader.cpp index 7dc813f869..fbe0e78777 100644 --- a/src/scenegraph/scenegraphloader.cpp +++ b/src/scenegraph/scenegraphloader.cpp @@ -17,7 +17,7 @@ #include namespace openspace { - +/* SceneGraph* loadSceneGraph(const std::string& sceneGraphPath) { SceneGraph* result = new SceneGraph; @@ -434,5 +434,6 @@ bool SceneGraphLoader::getShader(ghoul::opengl::ProgramObject **program, const s LERROR("Could not load shader"); return false; } + */ } // namespace openspace \ No newline at end of file diff --git a/src/scenegraph/scenegraphloader.h b/src/scenegraph/scenegraphloader.h index 23e80b8345..f4117fb521 100644 --- a/src/scenegraph/scenegraphloader.h +++ b/src/scenegraph/scenegraphloader.h @@ -14,9 +14,10 @@ #include "ghoul/opengl/texture.h" // sgct includes -#include "external/tinyxml2.h" +//#include "ext/tinyxml2.h" namespace openspace { + /* class SceneGraph; @@ -48,6 +49,7 @@ private: bool getShader(ghoul::opengl::ProgramObject **program, const std::string &path, tinyxml2::XMLElement *xmlnode); }; + */ } // namespace openspace diff --git a/src/scenegraph/scenegraphnode.cpp b/src/scenegraph/scenegraphnode.cpp index 78c2bc742d..b5dbd6c31d 100644 --- a/src/scenegraph/scenegraphnode.cpp +++ b/src/scenegraph/scenegraphnode.cpp @@ -229,7 +229,7 @@ bool SceneGraphNode::sphereInsideFrustum(const psc s_pos, const pss & s_rad, con // check if outside the maximum angle if (nodeName_ == "earth") { - psc tmp = s_pos - camera->getPosition(); + //psc tmp = s_pos - camera->getPosition(); //LINFOC("", "Angle: " << psc_camdir.angle(D)); //LINFOC("", "Pos: " << tmp.getVec4f()[0] << " " << tmp.getVec4f()[1] << " " << tmp.getVec4f()[2] << " " << tmp.getVec4f()[3]); diff --git a/src/scenegraph/scenegraphnode.h b/src/scenegraph/scenegraphnode.h index 97a9f8aa7b..efeb8158ab 100644 --- a/src/scenegraph/scenegraphnode.h +++ b/src/scenegraph/scenegraphnode.h @@ -48,6 +48,7 @@ public: else for (auto it : children_) return it->get(name); + return nullptr; } void print() const { diff --git a/src/util/geometry.h b/src/util/geometry.h index ec14f76f22..f87758845e 100644 --- a/src/util/geometry.h +++ b/src/util/geometry.h @@ -20,7 +20,7 @@ namespace gl4 public: //initializers Geometry(); - ~Geometry(); + virtual ~Geometry(); virtual void init(); glm::mat4 getTransform(); diff --git a/src/util/vbo.h b/src/util/vbo.h index 8d2c8b2026..136523809b 100644 --- a/src/util/vbo.h +++ b/src/util/vbo.h @@ -11,7 +11,8 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI #define VBO_H // sgct includes -#include "sgct.h" +//#include "sgct.h" +#include #define BUFFER_OFFSET(i) ((char *)NULL + (i)) diff --git a/src/util/vbo_template.h b/src/util/vbo_template.h index 028a919d0a..e14996364d 100644 --- a/src/util/vbo_template.h +++ b/src/util/vbo_template.h @@ -19,7 +19,8 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI #include "ghoul/logging/consolelog.h" // sgct includes -#include "sgct.h" +//#include "sgct.h" +#include #define BUFFER_OFFSET(i) ((char *)NULL + (i))