From a5ee211dbf0cd6a12cc2eb01f97750422775ec9a Mon Sep 17 00:00:00 2001
From: samcake <samuel.gateau@gmail.com>
Date: Thu, 5 Apr 2018 18:04:35 -0700
Subject: [PATCH] Dirty attempt to capture the owner typefor a payload

---
 interface/src/workload/PhysicsBoundary.h      | 12 ++++-----
 .../src/EntityTreeRenderer.cpp                |  2 +-
 libraries/workload/src/workload/Proxy.h       | 25 ++++++++++++++++---
 3 files changed, 29 insertions(+), 10 deletions(-)

diff --git a/interface/src/workload/PhysicsBoundary.h b/interface/src/workload/PhysicsBoundary.h
index 8f5c1a48ff..4109418e27 100644
--- a/interface/src/workload/PhysicsBoundary.h
+++ b/interface/src/workload/PhysicsBoundary.h
@@ -61,12 +61,12 @@ public:
         uint32_t numExits = (uint32_t)regionChanges[exitIndex].size();
         for (uint32_t i = 0; i < numExits; ++i) {
             int32_t proxyID = regionChanges[exitIndex][i];
-            void* owner = space->getOwner(proxyID).get();
+            auto owner = space->getOwner(proxyID).get<EntityItemPointer>();
             if (owner) {
-                EntityItem* entity = static_cast<EntityItem*>(owner);
+                //EntityItem* entity = static_cast<EntityItem*>(owner);
                 std::cout << "adebug  - "
                     //<< owner
-                    << "  '" << entity->getName().toStdString() << "'"
+                    << "  '" << owner->getName().toStdString() << "'"
                     << std::endl;     // adebug
             }
         }
@@ -75,12 +75,12 @@ public:
         uint32_t numEntries = (uint32_t)regionChanges[enterIndex].size();
         for (uint32_t i = 0; i < numEntries; ++i) {
             int32_t proxyID = regionChanges[enterIndex][i];
-            void* owner = space->getOwner(proxyID).get();
+            auto owner = space->getOwner(proxyID).get<EntityItemPointer>();
             if (owner) {
-                EntityItem* entity = static_cast<EntityItem*>(owner);
+              //  EntityItem* entity = static_cast<EntityItem*>(owner);
                 std::cout << "adebug  + "
                     //<< owner
-                    << "  '" << entity->getName().toStdString() << "'"
+                    << "  '" << owner->getName().toStdString() << "'"
                     << std::endl;     // adebug
             }
         }
diff --git a/libraries/entities-renderer/src/EntityTreeRenderer.cpp b/libraries/entities-renderer/src/EntityTreeRenderer.cpp
index ac3afb3e2b..8a8b71218c 100644
--- a/libraries/entities-renderer/src/EntityTreeRenderer.cpp
+++ b/libraries/entities-renderer/src/EntityTreeRenderer.cpp
@@ -284,7 +284,7 @@ void EntityTreeRenderer::addPendingEntities(const render::ScenePointer& scene, r
                 auto spaceIndex = _space->allocateID();
                 workload::Sphere sphere(entity->getWorldPosition(), entity->getBoundingRadius());
                 workload::Transaction transaction;
-                transaction.reset(spaceIndex, sphere, workload::Owner(entity.get()));
+                transaction.reset(spaceIndex, sphere, workload::Owner(entity));
                 _space->enqueueTransaction(transaction);
                 entity->setSpaceIndex(spaceIndex);
                 connect(entity.get(), &EntityItem::spaceUpdate, this, &EntityTreeRenderer::handleSpaceUpdate, Qt::QueuedConnection);
diff --git a/libraries/workload/src/workload/Proxy.h b/libraries/workload/src/workload/Proxy.h
index 0c1c7363cd..d204bd8544 100644
--- a/libraries/workload/src/workload/Proxy.h
+++ b/libraries/workload/src/workload/Proxy.h
@@ -18,13 +18,32 @@ namespace workload {
 class Owner {
 public:
     Owner() = default;
-    Owner(void* data) : _data(data) {}
     Owner(const Owner& other) = default;
     Owner& operator=(const Owner& other) = default;
+
+    template <class T> Owner(const T& data) : _concept(std::make_shared<Model<T>>(data)) {}
+
     ~Owner() {}
-    void* get() const { return _data; }
+
+    template <class T> const T get() const { return std::static_pointer_cast<const Model<T>>(_concept)->_data; }
+
+protected:
+    class Concept {
+    public:
+        virtual ~Concept() = default;
+        
+    };
+    template <class T> class Model : public Concept {
+    public:
+        using Data = T;
+        Data _data;
+
+        Model(const Data& data) : _data(data) {}
+        virtual ~Model() = default;
+    };
+
 private:
-    void* _data { nullptr };
+    std::shared_ptr<Concept> _concept;
 };
 
 class Proxy {