added test suite for PropertyFlags, latest work on PropertyFlags

This commit is contained in:
ZappoMan 2014-06-04 11:41:09 -07:00
parent b48c70a7f7
commit 2b85145325
5 changed files with 392 additions and 18 deletions

View file

@ -11,49 +11,65 @@
//
// TODO:
// * implement decode
// * add operators
// * more operators, operator==, operator!=, operator!, operator~
// * iterator to enumerate the set values?
// * operator<<(enum) to work similar to set
#ifndef hifi_PropertyFlags_h
#define hifi_PropertyFlags_h
#include <algorithm>
#include <climits>
#include <QBitArray>
#include <QByteArray>
#include <SharedUtil.h>
template<typename Enum>class PropertyFlags {
public:
typedef Enum enum_type;
inline PropertyFlags() : _maxFlag(-1) { };
inline PropertyFlags() : _maxFlag(INT_MIN), _minFlag(INT_MAX) { };
inline PropertyFlags(const PropertyFlags& other) : _flags(other._flags), _maxFlag(other._maxFlag) {}
inline PropertyFlags(Enum flag) : _maxFlag(-1) { setHasProperty(flag); }
inline PropertyFlags(Enum flag) : _maxFlag(INT_MIN), _minFlag(INT_MAX) { setHasProperty(flag); }
void clear() { _flags.clear(); _maxFlag = -1; }
void clear() { _flags.clear(); _maxFlag = INT_MIN; _minFlag = INT_MAX; }
Enum firstFlag() const { return _minFlag; }
Enum lastFlag() const { return _maxFlag; }
void setHasProperty(Enum flag, bool value = true);
bool getHasProperty(Enum flag);
QByteArray encode();
void decode(const QByteArray& fromEncoded);
inline PropertyFlags& operator=(const PropertyFlags &other) { _flags = other._flags; _maxFlag = other._maxFlag; return *this; }
PropertyFlags& operator=(const PropertyFlags &other);
inline PropertyFlags& operator|=(PropertyFlags other) { _flags |= other._flags; _maxFlag = max(_maxFlag, other._maxFlag); return *this; }
inline PropertyFlags& operator|=(Enum flag) { PropertyFlags other(flag); _flags |= other._flags; _maxFlag = max(_maxFlag, other._maxFlag); return *this; }
PropertyFlags& operator|=(PropertyFlags other);
PropertyFlags& operator|=(Enum flag);
inline PropertyFlags& operator&=(PropertyFlags other) { _flags &= other._flags; shinkIfNeeded(); return *this; }
inline PropertyFlags& operator&=(Enum flag) { PropertyFlags other(flag); _flags &= other._flags; shinkIfNeeded(); return *this; }
PropertyFlags& operator&=(PropertyFlags other);
PropertyFlags& operator&=(Enum flag);
inline PropertyFlags& operator^=(PropertyFlags other) { _flags ^= other._flags; shinkIfNeeded(); return *this; }
inline PropertyFlags& operator^=(Enum flag) { PropertyFlags other(flag); _flags ^= other._flags; shinkIfNeeded(); return *this; }
PropertyFlags& operator^=(PropertyFlags other);
PropertyFlags& operator^=(Enum flag);
PropertyFlags& operator-=(PropertyFlags other);
PropertyFlags& operator-=(Enum flag);
inline PropertyFlags operator|(PropertyFlags other) const { PropertyFlags result(*this); result |= other; return result; }
inline PropertyFlags operator|(Enum flag) const { PropertyFlags result(*this); PropertyFlags other(flag); result |= other; return result; }
PropertyFlags operator|(PropertyFlags other) const;
PropertyFlags operator|(Enum flag) const;
inline PropertyFlags operator^(PropertyFlags other) const { PropertyFlags result(*this); result ^= other; return result; }
inline PropertyFlags operator^(Enum flag) const { PropertyFlags result(*this); PropertyFlags other(flag); result ^= other; return result; }
PropertyFlags operator&(PropertyFlags other) const;
PropertyFlags operator&(Enum flag) const;
PropertyFlags operator^(PropertyFlags other) const;
PropertyFlags operator^(Enum flag) const;
PropertyFlags operator-(PropertyFlags other) const;
PropertyFlags operator-(Enum flag) const;
inline PropertyFlags operator&(PropertyFlags other) const { PropertyFlags result(*this); result &= other; return result; }
inline PropertyFlags operator&(Enum flag) const { PropertyFlags result(*this); PropertyFlags other(flag); result &= other; return result; }
/*
inline PropertyFlags operator~() const { return PropertyFlags(Enum(~i)); }
@ -63,13 +79,21 @@ public:
private:
void shinkIfNeeded();
void debugDumpBits();
QBitArray _flags;
int _maxFlag;
int _minFlag;
};
template<typename Enum> inline void PropertyFlags<Enum>::setHasProperty(Enum flag, bool value) {
// keep track of our min flag
if (flag < _minFlag) {
if (value) {
_minFlag = flag;
}
}
if (flag > _maxFlag) {
if (value) {
_maxFlag = flag;
@ -78,7 +102,6 @@ template<typename Enum> inline void PropertyFlags<Enum>::setHasProperty(Enum fla
return; // bail early, we're setting a flag outside of our current _maxFlag to false, which is already the default
}
}
qDebug() << "_flags.setBit("<<flag<<")=" << value;
_flags.setBit(flag, value);
if (flag == _maxFlag && !value) {
@ -176,6 +199,137 @@ template<typename Enum> inline QByteArray PropertyFlags<Enum>::encode() {
template<typename Enum> inline void PropertyFlags<Enum>::decode(const QByteArray& fromEncoded) {
}
template<typename Enum> inline void PropertyFlags<Enum>::debugDumpBits() {
for(int i = 0; i < _flags.size(); i++) {
qDebug() << "bit[" << i << "]=" << _flags.at(i);
}
}
template<typename Enum> inline PropertyFlags<Enum>& PropertyFlags<Enum>::operator=(const PropertyFlags &other) {
_flags = other._flags;
_maxFlag = other._maxFlag;
return *this;
}
template<typename Enum> inline PropertyFlags<Enum>& PropertyFlags<Enum>::operator|=(PropertyFlags other) {
_flags |= other._flags;
_maxFlag = std::max(_maxFlag, other._maxFlag);
return *this;
}
template<typename Enum> inline PropertyFlags<Enum>& PropertyFlags<Enum>::operator|=(Enum flag) {
PropertyFlags other(flag);
_flags |= other._flags;
_maxFlag = std::max(_maxFlag, other._maxFlag);
return *this;
}
template<typename Enum> inline PropertyFlags<Enum>& PropertyFlags<Enum>::operator&=(PropertyFlags other) {
_flags &= other._flags;
shinkIfNeeded();
return *this;
}
template<typename Enum> inline PropertyFlags<Enum>& PropertyFlags<Enum>::operator&=(Enum flag) {
PropertyFlags other(flag);
_flags &= other._flags;
shinkIfNeeded();
return *this;
}
template<typename Enum> inline PropertyFlags<Enum>& PropertyFlags<Enum>::operator^=(PropertyFlags other) {
_flags ^= other._flags;
shinkIfNeeded();
return *this;
}
template<typename Enum> inline PropertyFlags<Enum>& PropertyFlags<Enum>::operator^=(Enum flag) {
PropertyFlags other(flag);
_flags ^= other._flags;
shinkIfNeeded();
return *this;
}
template<typename Enum> inline PropertyFlags<Enum>& PropertyFlags<Enum>::operator-=(PropertyFlags other) {
for(int flag = other.firstFlag(); flag <= other.lastFlag(); flag++) {
//qDebug() << "checking other.getHasProperty(flag) flag=" << flag;
if (other.getHasProperty(flag)) {
//qDebug() << "setting setHasProperty(flag) flag=" << flag;
setHasProperty(flag, false);
}
}
return *this;
}
template<typename Enum> inline PropertyFlags<Enum>& PropertyFlags<Enum>::operator-=(Enum flag) {
bool debug = false;
if (debug) {
qDebug() << "operator-=(Enum flag) flag=" << flag << "before...";
debugDumpBits();
}
setHasProperty(flag, false);
if (debug) {
qDebug() << "after...";
debugDumpBits();
}
return *this;
}
template<typename Enum> inline PropertyFlags<Enum> PropertyFlags<Enum>::operator|(PropertyFlags other) const {
PropertyFlags result(*this);
result |= other;
return result;
}
template<typename Enum> inline PropertyFlags<Enum> PropertyFlags<Enum>::operator|(Enum flag) const {
PropertyFlags result(*this);
PropertyFlags other(flag);
result |= other;
return result;
}
template<typename Enum> inline PropertyFlags<Enum> PropertyFlags<Enum>::operator&(PropertyFlags other) const {
PropertyFlags result(*this);
result &= other;
return result;
}
template<typename Enum> inline PropertyFlags<Enum> PropertyFlags<Enum>::operator&(Enum flag) const {
PropertyFlags result(*this);
PropertyFlags other(flag);
result &= other;
return result;
}
template<typename Enum> inline PropertyFlags<Enum> PropertyFlags<Enum>::operator^(PropertyFlags other) const {
PropertyFlags result(*this);
result ^= other;
return result;
}
template<typename Enum> inline PropertyFlags<Enum> PropertyFlags<Enum>::operator^(Enum flag) const {
PropertyFlags result(*this);
PropertyFlags other(flag);
result ^= other;
return result;
}
template<typename Enum> inline PropertyFlags<Enum> PropertyFlags<Enum>::operator-(PropertyFlags other) const {
PropertyFlags result(*this);
result -= other;
return result;
}
template<typename Enum> inline PropertyFlags<Enum> PropertyFlags<Enum>::operator-(Enum flag) const {
PropertyFlags result(*this);
result.setHasProperty(flag, false);
return result;
}
template<typename Enum> inline void PropertyFlags<Enum>::shinkIfNeeded() {
bool maxFlagWas = _maxFlag;
while (_maxFlag >= 0) {

View file

@ -0,0 +1,39 @@
cmake_minimum_required(VERSION 2.8)
if (WIN32)
cmake_policy (SET CMP0020 NEW)
endif (WIN32)
set(TARGET_NAME octree-tests)
set(ROOT_DIR ../..)
set(MACRO_DIR ${ROOT_DIR}/cmake/macros)
# setup for find modules
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/../../cmake/modules/")
#find_package(Qt5Network REQUIRED)
#find_package(Qt5Script REQUIRED)
#find_package(Qt5Widgets REQUIRED)
include(${MACRO_DIR}/SetupHifiProject.cmake)
setup_hifi_project(${TARGET_NAME} TRUE)
include(${MACRO_DIR}/AutoMTC.cmake)
auto_mtc(${TARGET_NAME} ${ROOT_DIR})
#qt5_use_modules(${TARGET_NAME} Network Script Widgets)
#include glm
include(${MACRO_DIR}/IncludeGLM.cmake)
include_glm(${TARGET_NAME} ${ROOT_DIR})
# link in the shared libraries
include(${MACRO_DIR}/LinkHifiLibrary.cmake)
link_hifi_library(shared ${TARGET_NAME} ${ROOT_DIR})
link_hifi_library(octree ${TARGET_NAME} ${ROOT_DIR})
IF (WIN32)
#target_link_libraries(${TARGET_NAME} Winmm Ws2_32)
ENDIF(WIN32)

View file

@ -0,0 +1,143 @@
//
// OctreeTests.h
// tests/physics/src
//
// Created by Brad Hefta-Gaub on 06/04/2014.
// Copyright 2014 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
//
#include <QDebug>
#include <PropertyFlags.h>
#include <SharedUtil.h>
#include "OctreeTests.h"
enum ModelPropertyList {
PROP_PAGED_PROPERTY,
PROP_CUSTOM_PROPERTIES_INCLUDED,
PROP_VISIBLE,
PROP_POSITION,
PROP_RADIUS,
PROP_MODEL_URL,
PROP_ROTATION,
PROP_COLOR,
PROP_SCRIPT,
PROP_ANIMATION_URL,
PROP_ANIMATION_FPS,
PROP_ANIMATION_FRAME_INDEX,
PROP_ANIMATION_PLAYING,
PROP_SHOULD_BE_DELETED
};
typedef PropertyFlags<ModelPropertyList> ModelPropertyFlags;
enum ParticlePropertyList {
PARTICLE_PROP_PAGED_PROPERTY,
PARTICLE_PROP_CUSTOM_PROPERTIES_INCLUDED,
PARTICLE_PROP_VISIBLE,
PARTICLE_PROP_POSITION,
PARTICLE_PROP_RADIUS,
PARTICLE_PROP_MODEL_URL,
PARTICLE_PROP_ROTATION,
PARTICLE_PROP_COLOR,
PARTICLE_PROP_SCRIPT,
PARTICLE_PROP_ANIMATION_URL,
PARTICLE_PROP_ANIMATION_FPS,
PARTICLE_PROP_ANIMATION_FRAME_INDEX,
PARTICLE_PROP_ANIMATION_PLAYING,
PARTICLE_PROP_SHOULD_BE_DELETED,
PARTICLE_PROP_VELOCITY,
PARTICLE_PROP_GRAVITY,
PARTICLE_PROP_DAMPING,
PARTICLE_PROP_MASS,
PARTICLE_PROP_LIFETIME,
PARTICLE_PROP_PAUSE_SIMULATION,
};
typedef PropertyFlags<ParticlePropertyList> ParticlePropertyFlags;
void OctreeTests::propertyFlagsTests() {
qDebug() << "******************************************************************************************";
qDebug() << "OctreeTests::propertyFlagsTests()";
{
qDebug() << "Test 1: ModelProperties: PROP_VISIBLE, PROP_POSITION, PROP_RADIUS, PROP_MODEL_URL, PROP_ROTATION";
ModelPropertyFlags props;
props.setHasProperty(PROP_VISIBLE);
props.setHasProperty(PROP_POSITION);
props.setHasProperty(PROP_RADIUS);
props.setHasProperty(PROP_MODEL_URL);
props.setHasProperty(PROP_ROTATION);
QByteArray encoded = props.encode();
qDebug() << "encoded=";
outputBufferBits((const unsigned char*)encoded.constData(), encoded.size());
}
{
qDebug() << "Test 2: ParticlePropertyFlags: PROP_VISIBLE, PARTICLE_PROP_ANIMATION_URL, PARTICLE_PROP_ANIMATION_FPS, "
"PARTICLE_PROP_ANIMATION_FRAME_INDEX, PARTICLE_PROP_ANIMATION_PLAYING, PARTICLE_PROP_PAUSE_SIMULATION";
ParticlePropertyFlags props2;
props2.setHasProperty(PARTICLE_PROP_VISIBLE);
props2.setHasProperty(PARTICLE_PROP_ANIMATION_URL);
props2.setHasProperty(PARTICLE_PROP_ANIMATION_FPS);
props2.setHasProperty(PARTICLE_PROP_ANIMATION_FRAME_INDEX);
props2.setHasProperty(PARTICLE_PROP_ANIMATION_PLAYING);
props2.setHasProperty(PARTICLE_PROP_PAUSE_SIMULATION);
QByteArray encoded = props2.encode();
qDebug() << "encoded=";
outputBufferBits((const unsigned char*)encoded.constData(), encoded.size());
qDebug() << "Test 2b: remove flag with setHasProperty() PARTICLE_PROP_PAUSE_SIMULATION";
props2.setHasProperty(PARTICLE_PROP_PAUSE_SIMULATION, false);
encoded = props2.encode();
qDebug() << "encoded=";
outputBufferBits((const unsigned char*)encoded.constData(), encoded.size());
}
{
qDebug() << "Test 3: ParticlePropertyFlags: using | operator";
ParticlePropertyFlags props;
props = ParticlePropertyFlags(PARTICLE_PROP_VISIBLE)
| ParticlePropertyFlags(PARTICLE_PROP_ANIMATION_URL)
| ParticlePropertyFlags(PARTICLE_PROP_ANIMATION_FPS)
| ParticlePropertyFlags(PARTICLE_PROP_ANIMATION_FRAME_INDEX)
| ParticlePropertyFlags(PARTICLE_PROP_ANIMATION_PLAYING)
| ParticlePropertyFlags(PARTICLE_PROP_PAUSE_SIMULATION);
QByteArray encoded = props.encode();
qDebug() << "encoded=";
outputBufferBits((const unsigned char*)encoded.constData(), encoded.size());
qDebug() << "Test 3b: remove flag with -= PARTICLE_PROP_PAUSE_SIMULATION";
props -= PARTICLE_PROP_PAUSE_SIMULATION;
encoded = props.encode();
qDebug() << "encoded=";
outputBufferBits((const unsigned char*)encoded.constData(), encoded.size());
}
qDebug() << "******************************************************************************************";
}
void OctreeTests::runAllTests() {
propertyFlagsTests();
}

View file

@ -0,0 +1,22 @@
//
// OctreeTests.h
// tests/physics/src
//
// Created by Brad Hefta-Gaub on 06/04/2014.
// Copyright 2014 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_OctreeTests_h
#define hifi_OctreeTests_h
namespace OctreeTests {
void propertyFlagsTests();
void runAllTests();
}
#endif // hifi_OctreeTests_h

16
tests/octree/src/main.cpp Normal file
View file

@ -0,0 +1,16 @@
//
// main.cpp
// tests/octree/src
//
// Copyright 2014 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
//
#include "OctreeTests.h"
int main(int argc, char** argv) {
OctreeTests::runAllTests();
return 0;
}