From 9f26836b436d5d31428650216be7ae43abce0e41 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Wed, 13 Jul 2016 14:03:53 -0700 Subject: [PATCH] added basic CollisionGeometryCache container --- .../physics/src/CollisionGeometryCache.cpp | 79 +++++++++++++++++++ .../physics/src/CollisionGeometryCache.h | 62 +++++++++++++++ 2 files changed, 141 insertions(+) create mode 100644 libraries/physics/src/CollisionGeometryCache.cpp create mode 100644 libraries/physics/src/CollisionGeometryCache.h diff --git a/libraries/physics/src/CollisionGeometryCache.cpp b/libraries/physics/src/CollisionGeometryCache.cpp new file mode 100644 index 0000000000..b474d44c32 --- /dev/null +++ b/libraries/physics/src/CollisionGeometryCache.cpp @@ -0,0 +1,79 @@ +// +// CollisionGeometryCache.cpp +// libraries/physcis/src +// +// Created by Andrew Meadows 2016.07.13 +// Copyright 2016 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 +//#include + +//#include "ShapeFactory.h" +#include "CollisionGeometryCache.h" + +int foo = 0; + +GeometryPointer createGeometryFromShape(CollisionGeometryCache::Key key) { + return std::make_shared(++foo); +} + +CollisionGeometryCache::CollisionGeometryCache() { +} + +CollisionGeometryCache::~CollisionGeometryCache() { + _geometryMap.clear(); + _pendingGarbage.clear(); +} + +GeometryPointer CollisionGeometryCache::getGeometry(CollisionGeometryCache::Key key) { + if (!key) { + return GeometryPointer(); + } + GeometryPointer geometry = 0; + + CollisionGeometryMap::const_iterator itr = _geometryMap.find(key); + if (itr != _geometryMap.end()) { + // make geometry and add it to map + geometry = createGeometryFromShape(key); + if (geometry) { + _geometryMap.insert(std::make_pair(key, geometry)); + } + } + return geometry; +} + +bool CollisionGeometryCache::releaseGeometry(CollisionGeometryCache::Key key) { + if (!key) { + return false; + } + CollisionGeometryMap::const_iterator itr = _geometryMap.find(key); + if (itr != _geometryMap.end()) { + assert((*itr).second.use_count() != 1); + if ((*itr).second.use_count() == 2) { + // we hold all of the references inside the cache so we'll try to delete later + _pendingGarbage.push_back(key); + } + return true; + } + return false; +} + +void CollisionGeometryCache::collectGarbage() { + int numShapes = _pendingGarbage.size(); + for (int i = 0; i < numShapes; ++i) { + CollisionGeometryCache::Key key = _pendingGarbage[i]; + CollisionGeometryMap::const_iterator itr = _geometryMap.find(key); + if (itr != _geometryMap.end()) { + if ((*itr).second.use_count() == 1) { + // we hold the only reference + _geometryMap.erase(itr); + } + } + } + _pendingGarbage.clear(); +} + diff --git a/libraries/physics/src/CollisionGeometryCache.h b/libraries/physics/src/CollisionGeometryCache.h new file mode 100644 index 0000000000..f6a7a6f3e8 --- /dev/null +++ b/libraries/physics/src/CollisionGeometryCache.h @@ -0,0 +1,62 @@ +// +// CollisionGeometryCache.h +// libraries/physcis/src +// +// Created by Andrew Meadows 2016.07.13 +// Copyright 2016 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_CollisionGeometryCache +#define hifi_CollisionGeometryCache + +#include +#include +#include +//#include +//#include + +class btCollisionShape; + +// BEGIN TEST HACK +using GeometryPointer = std::shared_ptr; +// END TEST HACK + +namespace std { + template <> + struct hash { + std::size_t operator()(btCollisionShape* key) const { + return (hash()((void*)key)); + } + }; +} + +class CollisionGeometryCache { +public: + using Key = btCollisionShape const *; + + CollisionGeometryCache(); + ~CollisionGeometryCache(); + + /// \return pointer to geometry + GeometryPointer getGeometry(Key key); + + /// \return true if geometry was found and released + bool releaseGeometry(Key key); + + /// delete geometries that have zero references + void collectGarbage(); + + // validation methods + uint32_t getNumGeometries() const { return (uint32_t)_geometryMap.size(); } + bool hasGeometry(Key key) const { return _geometryMap.find(key) == _geometryMap.end(); } + +private: + using CollisionGeometryMap = std::unordered_map; + CollisionGeometryMap _geometryMap; + std::vector _pendingGarbage; +}; + +#endif // hifi_CollisionGeometryCache