Merge pull request #6282 from jherico/externals

Runtime plugins fixes
This commit is contained in:
Clément Brisset 2015-11-06 19:30:40 -08:00
commit 2c27d18922
7 changed files with 76 additions and 32 deletions

View file

@ -18,12 +18,19 @@ macro(COPY_DLLS_BESIDE_WINDOWS_EXECUTABLE)
@ONLY
)
if (APPLE)
set(PLUGIN_PATH "interface.app/Contents/MacOS/plugins")
else()
set(PLUGIN_PATH "plugins")
endif()
# add a post-build command to copy DLLs beside the executable
add_custom_command(
TARGET ${TARGET_NAME}
POST_BUILD
COMMAND ${CMAKE_COMMAND}
-DBUNDLE_EXECUTABLE=$<TARGET_FILE:${TARGET_NAME}>
-DBUNDLE_PLUGIN_DIR=$<TARGET_FILE_DIR:${TARGET_NAME}>/${PLUGIN_PATH}
-P ${CMAKE_CURRENT_BINARY_DIR}/FixupBundlePostBuild.cmake
)

View file

@ -41,4 +41,16 @@ function(copy_resolved_item_into_bundle resolved_item resolved_embedded_item)
endfunction()
message(STATUS "FIXUP_LIBS for fixup_bundle called for bundle ${BUNDLE_EXECUTABLE} are @FIXUP_LIBS@")
fixup_bundle("${BUNDLE_EXECUTABLE}" "" "@FIXUP_LIBS@")
message(STATUS "Scanning for plugins from ${BUNDLE_PLUGIN_DIR}")
if (APPLE)
set(PLUGIN_EXTENSION "dylib")
elseif (WIN32)
set(PLUGIN_EXTENSION "dll")
else()
set(PLUGIN_EXTENSION "so")
endif()
file(GLOB RUNTIME_PLUGINS "${BUNDLE_PLUGIN_DIR}/*.${PLUGIN_EXTENSION}")
fixup_bundle("${BUNDLE_EXECUTABLE}" "${RUNTIME_PLUGINS}" "@FIXUP_LIBS@")

View file

@ -44,22 +44,11 @@
#include "Menu.h"
Menu* Menu::_instance = NULL;
static const char* const MENU_PROPERTY_NAME = "com.highfidelity.Menu";
Menu* Menu::getInstance() {
static QMutex menuInstanceMutex;
// lock the menu instance mutex to make sure we don't race and create two menus and crash
menuInstanceMutex.lock();
if (!_instance) {
qCDebug(interfaceapp, "First call to Menu::getInstance() - initing menu.");
_instance = new Menu();
}
menuInstanceMutex.unlock();
return _instance;
static Menu* instance = globalInstance<Menu>(MENU_PROPERTY_NAME);
return instance;
}
Menu::Menu() {

View file

@ -57,6 +57,7 @@ private:
class Menu : public QMenuBar {
Q_OBJECT
public:
Menu();
static Menu* getInstance();
void loadSettings();
@ -103,9 +104,6 @@ public slots:
void setIsOptionChecked(const QString& menuOption, bool isChecked);
private:
static Menu* _instance;
Menu();
typedef void(*settingsAction)(Settings&, QAction&);
static void loadAction(Settings& settings, QAction& action);
static void saveAction(Settings& settings, QAction& action);

View file

@ -11,8 +11,16 @@
#include "DependencyManager.h"
DependencyManager DependencyManager::_manager;
#include "SharedUtil.h"
#include "Finally.h"
static const char* const DEPENDENCY_PROPERTY_NAME = "com.highfidelity.DependencyMananger";
DependencyManager& DependencyManager::manager() {
static DependencyManager* instance = globalInstance<DependencyManager>(DEPENDENCY_PROPERTY_NAME);
return *instance;
}
QSharedPointer<Dependency>& DependencyManager::safeGet(size_t hashCode) {
return _instanceHash[hashCode];
}
}

View file

@ -62,8 +62,8 @@ public:
static void registerInheritance();
private:
static DependencyManager _manager;
static DependencyManager& manager();
template<typename T>
size_t getHashCode();
@ -75,11 +75,11 @@ private:
template <typename T>
QSharedPointer<T> DependencyManager::get() {
static size_t hashCode = _manager.getHashCode<T>();
static size_t hashCode = manager().getHashCode<T>();
static QWeakPointer<T> instance;
if (instance.isNull()) {
instance = qSharedPointerCast<T>(_manager.safeGet(hashCode));
instance = qSharedPointerCast<T>(manager().safeGet(hashCode));
if (instance.isNull()) {
qWarning() << "DependencyManager::get(): No instance available for" << typeid(T).name();
@ -91,9 +91,9 @@ QSharedPointer<T> DependencyManager::get() {
template <typename T, typename ...Args>
QSharedPointer<T> DependencyManager::set(Args&&... args) {
static size_t hashCode = _manager.getHashCode<T>();
static size_t hashCode = manager().getHashCode<T>();
QSharedPointer<Dependency>& instance = _manager.safeGet(hashCode);
QSharedPointer<Dependency>& instance = manager().safeGet(hashCode);
instance.clear(); // Clear instance before creation of new one to avoid edge cases
QSharedPointer<T> newInstance(new T(args...), &T::customDeleter);
QSharedPointer<Dependency> storedInstance = qSharedPointerCast<Dependency>(newInstance);
@ -104,9 +104,9 @@ QSharedPointer<T> DependencyManager::set(Args&&... args) {
template <typename T, typename I, typename ...Args>
QSharedPointer<T> DependencyManager::set(Args&&... args) {
static size_t hashCode = _manager.getHashCode<T>();
static size_t hashCode = manager().getHashCode<T>();
QSharedPointer<Dependency>& instance = _manager.safeGet(hashCode);
QSharedPointer<Dependency>& instance = manager().safeGet(hashCode);
instance.clear(); // Clear instance before creation of new one to avoid edge cases
QSharedPointer<T> newInstance(new I(args...), &I::customDeleter);
QSharedPointer<Dependency> storedInstance = qSharedPointerCast<Dependency>(newInstance);
@ -117,15 +117,15 @@ QSharedPointer<T> DependencyManager::set(Args&&... args) {
template <typename T>
void DependencyManager::destroy() {
static size_t hashCode = _manager.getHashCode<T>();
_manager.safeGet(hashCode).clear();
static size_t hashCode = manager().getHashCode<T>();
manager().safeGet(hashCode).clear();
}
template<typename Base, typename Derived>
void DependencyManager::registerInheritance() {
size_t baseHashCode = typeid(Base).hash_code();
size_t derivedHashCode = typeid(Derived).hash_code();
_manager._inheritanceHash.insert(baseHashCode, derivedHashCode);
manager()._inheritanceHash.insert(baseHashCode, derivedHashCode);
}
template<typename T>

View file

@ -13,6 +13,7 @@
#define hifi_SharedUtil_h
#include <memory>
#include <mutex>
#include <math.h>
#include <stdint.h>
@ -20,7 +21,36 @@
#include <unistd.h> // not on windows, not needed for mac or windows
#endif
#include <QDebug>
#include <QtCore/QDebug>
#include <QtCore/QCoreApplication>
// Provides efficient access to a named global type. By storing the value
// in the QApplication by name we can implement the singleton pattern and
// have the single instance function across DLL boundaries.
template <typename T, typename... Args>
T* globalInstance(const char* propertyName, Args&&... args) {
static std::unique_ptr<T> instancePtr;
static T* resultInstance { nullptr };
static std::mutex mutex;
if (!resultInstance) {
std::unique_lock<std::mutex> lock(mutex);
if (!resultInstance) {
auto variant = qApp->property(propertyName);
if (variant.isNull()) {
// Since we're building the object, store it in a shared_ptr so it's
// destroyed by the destructor of the static instancePtr
instancePtr = std::unique_ptr<T>(new T(std::forward<Args>(args)...));
void* voidInstance = &(*instancePtr);
variant = QVariant::fromValue(voidInstance);
qApp->setProperty(propertyName, variant);
}
void* returnedVoidInstance = variant.value<void*>();
resultInstance = static_cast<T*>(returnedVoidInstance);
}
}
return resultInstance;
}
const int BYTES_PER_COLOR = 3;
const int BYTES_PER_FLAGS = 1;