From 21121d5ba57846b48667fcbb1620f1d60dddbcdb Mon Sep 17 00:00:00 2001
From: Chris Robinson <chris.kcat@gmail.com>
Date: Fri, 16 Aug 2013 04:18:48 -0700
Subject: [PATCH] Store the object class in the LiveCellRef

---
 apps/openmw/mwworld/class.cpp       |  5 +++--
 apps/openmw/mwworld/class.hpp       |  8 +++++++-
 apps/openmw/mwworld/livecellref.hpp |  7 +++----
 apps/openmw/mwworld/ptr.cpp         | 15 +++++++++++++++
 apps/openmw/mwworld/ptr.hpp         | 10 ++++++----
 5 files changed, 34 insertions(+), 11 deletions(-)

diff --git a/apps/openmw/mwworld/class.cpp b/apps/openmw/mwworld/class.cpp
index c7b8d341c1..c739ea831c 100644
--- a/apps/openmw/mwworld/class.cpp
+++ b/apps/openmw/mwworld/class.cpp
@@ -245,9 +245,10 @@ namespace MWWorld
         throw std::runtime_error ("class does not support persistence");
     }
 
-    void Class::registerClass (const std::string& key,  boost::shared_ptr<Class> instance)
+    void Class::registerClass(const std::string& key,  boost::shared_ptr<Class> instance)
     {
-        sClasses.insert (std::make_pair (key, instance));
+        instance->mTypeName = key;
+        sClasses.insert(std::make_pair(key, instance));
     }
 
     std::string Class::getUpSoundId (const Ptr& ptr) const
diff --git a/apps/openmw/mwworld/class.hpp b/apps/openmw/mwworld/class.hpp
index c910000525..28e37cbf3c 100644
--- a/apps/openmw/mwworld/class.hpp
+++ b/apps/openmw/mwworld/class.hpp
@@ -50,6 +50,8 @@ namespace MWWorld
     {
             static std::map<std::string, boost::shared_ptr<Class> > sClasses;
 
+            std::string mTypeName;
+
             // not implemented
             Class (const Class&);
             Class& operator= (const Class&);
@@ -73,6 +75,10 @@ namespace MWWorld
 
             virtual ~Class();
 
+            const std::string& getTypeName() const {
+                return mTypeName;
+            }
+
             virtual std::string getId (const Ptr& ptr) const;
             ///< Return ID of \a ptr or throw an exception, if class does not support ID retrieval
             /// (default implementation: throw an exception)
@@ -292,7 +298,7 @@ namespace MWWorld
 
             static const Class& get (const Ptr& ptr)
             {
-                return get(ptr.getTypeName());
+                return ptr.getClass();
             }
             ///< If there is no class for this pointer, an exception is thrown.
 
diff --git a/apps/openmw/mwworld/livecellref.hpp b/apps/openmw/mwworld/livecellref.hpp
index 64462cb3fd..415351e783 100644
--- a/apps/openmw/mwworld/livecellref.hpp
+++ b/apps/openmw/mwworld/livecellref.hpp
@@ -11,11 +11,12 @@ namespace MWWorld
 {
     class Ptr;
     class ESMStore;
+    class Class;
 
     /// Used to create pointers to hold any type of LiveCellRef<> object.
     struct LiveCellRefBase
     {
-        std::string mTypeName;
+        const Class *mClass;
 
         /** Information about this instance, such as 3D location and rotation
          * and individual type-dependent data.
@@ -25,9 +26,7 @@ namespace MWWorld
         /** runtime-data */
         RefData mData;
 
-        LiveCellRefBase(std::string type, const ESM::CellRef &cref=ESM::CellRef())
-          : mTypeName(type), mRef(cref), mData(mRef)
-        { }
+        LiveCellRefBase(std::string type, const ESM::CellRef &cref=ESM::CellRef());
         /* Need this for the class to be recognized as polymorphic */
         virtual ~LiveCellRefBase() { }
     };
diff --git a/apps/openmw/mwworld/ptr.cpp b/apps/openmw/mwworld/ptr.cpp
index 34fe7fa08a..127ab1364c 100644
--- a/apps/openmw/mwworld/ptr.cpp
+++ b/apps/openmw/mwworld/ptr.cpp
@@ -4,8 +4,23 @@
 #include <cassert>
 
 #include "containerstore.hpp"
+#include "class.hpp"
 
 
+/* This shouldn't really be here. */
+MWWorld::LiveCellRefBase::LiveCellRefBase(std::string type, const ESM::CellRef &cref)
+  : mClass(&Class::get(type)), mRef(cref), mData(mRef)
+{
+}
+
+
+const std::string& MWWorld::Ptr::getTypeName() const
+{
+    if(mRef != 0)
+        return mRef->mClass->getTypeName();
+    throw std::runtime_error("Can't get type name from an empty object.");
+}
+
 ESM::CellRef& MWWorld::Ptr::getCellRef() const
 {
     assert(mRef);
diff --git a/apps/openmw/mwworld/ptr.hpp b/apps/openmw/mwworld/ptr.hpp
index 51c1530d7e..e5352da280 100644
--- a/apps/openmw/mwworld/ptr.hpp
+++ b/apps/openmw/mwworld/ptr.hpp
@@ -32,11 +32,13 @@ namespace MWWorld
                 return mRef == 0;
             }
 
-            const std::string& getTypeName() const
+            const std::string& getTypeName() const;
+
+            const Class& getClass() const
             {
                 if(mRef != 0)
-                    return mRef->mTypeName;
-                throw std::runtime_error("Can't get type name from an empty object.");
+                    return *(mRef->mClass);
+                throw std::runtime_error("Cannot get class of an empty object");
             }
 
             template<typename T>
@@ -47,7 +49,7 @@ namespace MWWorld
 
                 std::stringstream str;
                 str<< "Bad LiveCellRef cast to "<<typeid(T).name()<<" from ";
-                if(mRef != 0) str<< mRef->mTypeName;
+                if(mRef != 0) str<< getTypeName();
                 else str<< "an empty object";
 
                 throw std::runtime_error(str.str());