237 lines · 7.7 KB · C
RawDownload
////  SharedUtil.h//  libraries/shared/src////  Created by Stephen Birarda on 2/22/13.//  Copyright 2013 High Fidelity, Inc.////  Distributed under the Apache License, Version 2.0.//  See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html// #ifndef hifi_SharedUtil_h#define hifi_SharedUtil_h #include <memory>#include <mutex>#include <math.h>#include <stdint.h> #ifndef _WIN32#include <unistd.h> // not on windows, not needed for mac or windows#endif #include <QtCore/QDebug>#include <QtCore/QCoreApplication>#include <QUuid> #include "NumericalConstants.h"// When writing out avatarEntities to a QByteArray, if the parentID is the ID of MyAvatar, use this ID instead.  This allows// the value to be reset when the sessionID changes.const QUuid AVATAR_SELF_ID = QUuid("{00000000-0000-0000-0000-000000000001}"); // Access to the global instance pointer to enable setting / unsettingtemplate <typename T>std::unique_ptr<T>& globalInstancePointer() {    static std::unique_ptr<T> instancePtr;    return instancePtr;} // Sets up the global instances for use// This NEEDS to be called on startup// for any binary planing on using global instances// More details in cpp filevoid setupGlobalInstances(); std::mutex& globalInstancesMutex();QVariant getGlobalInstance(const char* propertyName);void setGlobalInstance(const char* propertyName, const QVariant& variant); // 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 T* resultInstance { nullptr };    if (!resultInstance) {        std::unique_lock<std::mutex> lock(globalInstancesMutex());        if (!resultInstance) {            auto variant = getGlobalInstance(propertyName);            if (variant.isNull()) {                std::unique_ptr<T>& instancePtr = globalInstancePointer<T>();                if (!instancePtr.get()) {                    // 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);                setGlobalInstance(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;typedef unsigned char colorPart;typedef unsigned char nodeColor[BYTES_PER_COLOR + BYTES_PER_FLAGS]; // Equivalent to time_t but in usecs instead of secsquint64 usecTimestampNow(bool wantDebug = false);void usecTimestampNowForceClockSkew(qint64 clockSkew); inline bool afterUsecs(quint64& startUsecs, quint64 maxIntervalUecs) {    auto now = usecTimestampNow();    auto interval = now - startUsecs;    if (interval > maxIntervalUecs) {        startUsecs = now;        return true;    }    return false;} inline bool afterSecs(quint64& startUsecs, quint64 maxIntervalSecs) {    return afterUsecs(startUsecs, maxIntervalSecs * USECS_PER_SECOND);} template <typename F>void doEvery(quint64& lastReportUsecs, quint64 secs, F lamdba) {    if (afterSecs(lastReportUsecs, secs)) {        lamdba();    }} // Number of seconds expressed since the first call to this function, expressed as a float// Maximum accuracy in msecsfloat secTimestampNow(); // Custom deleter for QObjects that calls deleteLaterstruct LaterDeleter {    void operator()(QObject* ptr) {        ptr->deleteLater();    }}; float randFloat();int randIntInRange (int min, int max);float randFloatInRange (float min,float max);float randomSign(); /// \return -1.0 or 1.0unsigned char randomColorValue(int minimum = 0);bool randomBoolean(); bool shouldDo(float desiredInterval, float deltaTime); void outputBufferBits(const unsigned char* buffer, int length, QDebug* continuedDebug = NULL);void outputBits(unsigned char byte, QDebug* continuedDebug = NULL);void printVoxelCode(unsigned char* voxelCode);int numberOfOnes(unsigned char byte);bool oneAtBit(unsigned char byte, int bitIndex);void setAtBit(unsigned char& byte, int bitIndex);bool oneAtBit16(unsigned short word, int bitIndex);void setAtBit16(unsigned short& word, int bitIndex);void clearAtBit(unsigned char& byte, int bitIndex);int  getSemiNibbleAt(unsigned short word, int bitIndex);void setSemiNibbleAt(unsigned short& word, int bitIndex, int value); int getNthBit(unsigned char byte, int ordinal); /// determines the bit placement 0-7 of the ordinal set bit bool isInEnvironment(const char* environment); const char* getCmdOption(int argc, const char * argv[],const char* option);bool cmdOptionExists(int argc, const char * argv[],const char* option); void sharedMessageHandler(QtMsgType type, const QMessageLogContext& context, const QString &message); unsigned char* pointToVoxel(float x, float y, float z, float s, unsigned char r = 0, unsigned char g = 0, unsigned char b = 0);unsigned char* pointToOctalCode(float x, float y, float z, float s); #ifdef _WIN32void usleep(int waitTime);#endif int insertIntoSortedArrays(void* value, float key, int originalIndex,                           void** valueArray, float* keyArray, int* originalIndexArray,                           int currentCount, int maxCount); int removeFromSortedArrays(void* value, void** valueArray, float* keyArray, int* originalIndexArray,                           int currentCount, int maxCount); // Helper Class for debuggingclass debug {public:    static const char* valueOf(bool checkValue) { return checkValue ? "yes" : "no"; }    static void setDeadBeef(void* memoryVoid, int size);    static void checkDeadBeef(void* memoryVoid, int size);private:    static unsigned char DEADBEEF[];    static int DEADBEEF_SIZE;}; /// \return true when value is between max and mininline bool isBetween(int64_t value, int64_t max, int64_t min) { return ((value <= max) && (value >= min)); } /// \return bool is the float NaNinline bool isNaN(float value) { return value != value; } QString formatUsecTime(float usecs);QString formatUsecTime(double usecs);QString formatUsecTime(quint64 usecs);QString formatUsecTime(qint64 usecs);QString formatSecTime(qint64 secs); QString formatSecondsElapsed(float seconds);bool similarStrings(const QString& stringA, const QString& stringB); template <typename T>uint qHash(const std::shared_ptr<T>& ptr, uint seed = 0){    return qHash(ptr.get(), seed);} void disableQtBearerPoll(); void printSystemInformation(); struct MemoryInfo {    uint64_t totalMemoryBytes;    uint64_t availMemoryBytes;    uint64_t usedMemoryBytes;    uint64_t processUsedMemoryBytes;    uint64_t processPeakUsedMemoryBytes;}; bool getMemoryInfo(MemoryInfo& info); struct ProcessorInfo {    int32_t numPhysicalProcessorPackages;    int32_t numProcessorCores;    int32_t numLogicalProcessors;    int32_t numProcessorCachesL1;    int32_t numProcessorCachesL2;    int32_t numProcessorCachesL3;}; bool getProcessorInfo(ProcessorInfo& info); const QString& getInterfaceSharedMemoryName(); void setMaxCores(uint8_t maxCores); const QString PARENT_PID_OPTION = "parent-pid";void watchParentProcess(int parentPID); bool processIsRunning(int64_t pid); void setupHifiApplication(QString applicationName); #ifdef Q_OS_WINvoid* createProcessGroup();void addProcessToGroup(void* processGroup, qint64 processId);#endif #endif // hifi_SharedUtil_h