NLS Engine  v0.1
The Next Logical Step in game engine design.
 All Classes Namespaces Files Functions Variables Enumerations Enumerator Defines
Envelope.cpp
Go to the documentation of this file.
00001 
00008 #include "Envelope.h"
00009 
00010 // Standard Includes
00011 
00012 // Library Includes
00013 #include <boost/any.hpp>
00014 #include <boost/foreach.hpp>
00015 #include <boost/lexical_cast.hpp>
00016 #include <boost/property_tree/ptree.hpp>
00017 #include <boost/property_tree/json_parser.hpp>
00018 #include <EngineConfig.h>
00019 
00020 // Local Includes
00021 #include "EventLogger.h"
00022 #include "Entity.h"
00023 
00024 // Local Consts
00025 const std::string SERIALIZATION_ROOT("NLS_SD_1_0_0");
00026 
00027 // Static class member initialization
00028 
00029 // Class methods in the order they are defined within the class header
00030 
00031 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
00032 void SaveToDisk(const EnvelopeSPTR& envelope, const std::string& file) {
00033   boost::property_tree::ptree property_tree;
00034   std::string filename = file;
00035   
00036   LOG(LOG_PRIORITY::INFO, "Saving to disk in '" + filename + "'...");
00037   
00038   envelope->SaveToPropertyTree(property_tree, SERIALIZATION_ROOT + "");
00039   
00040   write_json(filename, property_tree);
00041   
00042   LOG(LOG_PRIORITY::INFO, "Completed saving to '" + filename + "'.");
00043 }
00044 
00045 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
00046 bool LoadFromDisk(const EnvelopeSPTR& envelope, const std::string& file) {
00047   std::string filename = file;
00048   
00049   // Prevent loading if there is any member data already.
00050   if (envelope->GetCount() > 0) {
00051     LOG(LOG_PRIORITY::INFO, "Cannot load from '" + filename + "' because the Envelope already contains data.");
00052     return false;
00053   }
00054   
00055   boost::property_tree::ptree property_tree;
00056   
00057   LOG(LOG_PRIORITY::INFO, "Loading from'" + filename + "'...");
00058   
00059   try {
00060     read_json(filename, property_tree);
00061   }
00062   catch (boost::property_tree::file_parser_error& exception) {
00063     LOG(LOG_PRIORITY::INFO, "Error '" + exception.message() + "' trying to read file: " + exception.filename());
00064     return false;
00065   }
00066   
00067   envelope->LoadFromPropertyTree(property_tree, SERIALIZATION_ROOT + "");
00068   // *BUG: *TODO: catch any bad parsing errors from malformed files, etc.
00069   
00070   LOG(LOG_PRIORITY::INFO, "Completed loading from'" + filename + "'.");
00071   return true;
00072 }
00073 
00074 
00075 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
00076 Envelope::Envelope() :
00077   msgid(0)
00078   {
00079 }
00080 
00081 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
00082 boost::any Envelope::GetData(const unsigned int& index) {
00083   Threading::ReadLock r_lock(this->mutex);
00084   
00085   return this->data.at(index).data;
00086 }
00087 
00088 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
00089 boost::any Envelope::GetData(const unsigned int& index) const {
00090   Threading::ReadLock r_lock(this->mutex);
00091   
00092   return this->data.at(index).data;
00093 }
00094 
00095 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
00096 bool           Envelope::GetDataBool  (const unsigned int& index) { return this->GetDataValue<bool>          (index); }
00097 int            Envelope::GetDataInt   (const unsigned int& index) { return this->GetDataValue<int>           (index); }
00098 long           Envelope::GetDataLong  (const unsigned int& index) { return this->GetDataValue<long>          (index); }
00099 unsigned int   Envelope::GetDataUInt  (const unsigned int& index) { return this->GetDataValue<unsigned int>  (index); }
00100 float          Envelope::GetDataFloat (const unsigned int& index) { return this->GetDataValue<float>         (index); }
00101 std::string    Envelope::GetDataString(const unsigned int& index) { return this->GetDataValue<std::string>   (index); }
00102 D3DXVECTOR3    Envelope::GetDataVector(const unsigned int& index) { return this->GetDataValue<D3DXVECTOR3>   (index); }
00103 D3DXQUATERNION Envelope::GetDataQuat  (const unsigned int& index) { return this->GetDataValue<D3DXQUATERNION>(index); }
00104 D3DXCOLOR      Envelope::GetDataColor (const unsigned int& index) { return this->GetDataValue<D3DXCOLOR>     (index); }
00105 
00106 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
00107 EntitySPTR   Envelope::GetDataEntityP     (const unsigned int& index) { EntitySPTR   sptr(this->GetDataReference<EntitySPTR>(index));   return sptr; }
00108 Envelope*    Envelope::GetDataEnvelopeP   (const unsigned int& index) { Envelope*     ptr(this->GetDataReference<Envelope*> (index));   return  ptr; }
00109 EnvelopeSPTR Envelope::GetDataEnvelopeSPTR(const unsigned int& index) { EnvelopeSPTR sptr(this->GetDataReference<EnvelopeSPTR>(index)); return sptr; }
00110 
00111 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
00112 unsigned int Envelope::GetCount() {
00113   Threading::ReadLock r_lock(this->mutex); 
00114   
00115   return this->data.size();
00116 }
00117 
00118 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
00119 void Envelope::SaveToPropertyTree(boost::property_tree::ptree& property_tree, const std::string& parent_key) {
00120   Threading::ReadLock r_lock(this->mutex);
00121   
00122   LOG(LOG_PRIORITY::INFO, "Saving Envelope(" + boost::lexical_cast<std::string>(this->msgid) + ")'s data to property map...");
00123   
00124   // Store the message id
00125   property_tree.put(parent_key + ".message_id", this->msgid);
00126   
00127   unsigned int counter = 0;
00128   
00129   // Store the data
00130   BOOST_FOREACH(EnvelopeItem datum, this->data) {
00131     if (datum.data.type() == typeid(bool)) {
00132       property_tree.put(parent_key + ".data.item" + boost::lexical_cast<std::string>(counter) + "." + datum.type, boost::any_cast<bool>(datum.data));
00133     }
00134     else if (datum.data.type() == typeid(int)) {
00135       property_tree.put(parent_key + ".data.item" + boost::lexical_cast<std::string>(counter) + "." + datum.type, boost::any_cast<int>(datum.data));
00136     }
00137     else if (datum.data.type() == typeid(long)) {
00138       property_tree.put(parent_key + ".data.item" + boost::lexical_cast<std::string>(counter) + "." + datum.type, boost::any_cast<long>(datum.data));
00139     }
00140     else if (datum.data.type() == typeid(unsigned int)) {
00141       property_tree.put(parent_key + ".data.item" + boost::lexical_cast<std::string>(counter) + "." + datum.type, boost::any_cast<unsigned int>(datum.data));
00142     }
00143     else if (datum.data.type() == typeid(float)) {
00144       property_tree.put(parent_key + ".data.item" + boost::lexical_cast<std::string>(counter) + "." + datum.type, boost::any_cast<float>(datum.data));
00145     }
00146     else if (datum.data.type() == typeid(std::string)) {
00147       property_tree.put(parent_key + ".data.item" + boost::lexical_cast<std::string>(counter) + ".string", boost::any_cast<std::string>(datum.data));
00148     }
00149     else if (datum.data.type() == typeid(D3DXVECTOR3)) {
00150       D3DXVECTOR3 vector = boost::any_cast<D3DXVECTOR3>(datum.data);
00151       
00152       property_tree.put(parent_key + ".data.item" + boost::lexical_cast<std::string>(counter) + ".vector3.x", vector.x);
00153       property_tree.put(parent_key + ".data.item" + boost::lexical_cast<std::string>(counter) + ".vector3.y", vector.y);
00154       property_tree.put(parent_key + ".data.item" + boost::lexical_cast<std::string>(counter) + ".vector3.z", vector.z);
00155     }
00156     else if (datum.data.type() == typeid(D3DXQUATERNION)) {
00157       D3DXQUATERNION quat = boost::any_cast<D3DXQUATERNION>(datum.data);
00158       
00159       property_tree.put(parent_key + ".data.item" + boost::lexical_cast<std::string>(counter) + ".quat.x", quat.x);
00160       property_tree.put(parent_key + ".data.item" + boost::lexical_cast<std::string>(counter) + ".quat.y", quat.y);
00161       property_tree.put(parent_key + ".data.item" + boost::lexical_cast<std::string>(counter) + ".quat.z", quat.z);
00162       property_tree.put(parent_key + ".data.item" + boost::lexical_cast<std::string>(counter) + ".quat.w", quat.w);
00163     }
00164     else if (datum.data.type() == typeid(D3DXCOLOR)) {
00165       D3DXCOLOR color = boost::any_cast<D3DXCOLOR>(datum.data);
00166       
00167       property_tree.put(parent_key + ".data.color.item" + boost::lexical_cast<std::string>(counter) + ".r", color.r);
00168       property_tree.put(parent_key + ".data.color.item" + boost::lexical_cast<std::string>(counter) + ".g", color.g);
00169       property_tree.put(parent_key + ".data.color.item" + boost::lexical_cast<std::string>(counter) + ".b", color.b);
00170       property_tree.put(parent_key + ".data.color.item" + boost::lexical_cast<std::string>(counter) + ".a", color.a);
00171     }
00172     else if (datum.data.type() == typeid(Envelope*)) {
00173       LOG(LOG_PRIORITY::INFO, "Serializing an Envelope pointer unsupported at this time - please use an EnvelopeSPTR.");
00174     }
00175     else if (datum.data.type() == typeid(EnvelopeSPTR)) {
00176       boost::any_cast<EnvelopeSPTR>(datum.data)->SaveToPropertyTree(property_tree, parent_key + ".data.item" + boost::lexical_cast<std::string>(counter) + ".envelope");
00177     }
00178     else {
00179       LOG(LOG_PRIORITY::INFO, "Serializing an " + std::string(datum.data.type().name()) + " unsupported at this time.");
00180     }
00181     counter++;
00182   }
00183 }
00184 
00185 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
00186 void Envelope::LoadFromPropertyTree(boost::property_tree::ptree& property_tree, const std::string& parent_key) {
00187   LOG(LOG_PRIORITY::INFO, "Loading envelope data...");
00188   
00189   BOOST_FOREACH(boost::property_tree::ptree::value_type& value, property_tree.get_child(parent_key)) {
00190     if (value.first == "message_id") {
00191       this->msgid = boost::lexical_cast<int>(value.second.data());
00192     }
00193     else if (value.first == "data") {
00194       boost::property_tree::ptree data = value.second;
00195       
00196       BOOST_FOREACH(boost::property_tree::ptree::value_type& value, data) {
00197         boost::property_tree::ptree datum = value.second;
00198         
00199         boost::property_tree::ptree::iterator it;
00200         if ((it = datum.to_iterator(datum.find("bool"))) != datum.end()) {
00201           this->AddData(boost::lexical_cast<bool>(it->second.data()));
00202         }
00203         else if ((it = datum.to_iterator(datum.find("int"))) != datum.end()) {
00204           this->AddData(boost::lexical_cast<int>(it->second.data()));
00205         }
00206         else if ((it = datum.to_iterator(datum.find("long"))) != datum.end()) {
00207           this->AddData(boost::lexical_cast<long>(it->second.data()));
00208         }
00209         else if ((it = datum.to_iterator(datum.find("unsigned int"))) != datum.end()) {
00210           this->AddData(boost::lexical_cast<unsigned int>(it->second.data()));
00211         }
00212         else if ((it = datum.to_iterator(datum.find("float"))) != datum.end()) {
00213           this->AddData(boost::lexical_cast<float>(it->second.data()));
00214         }
00215         else if ((it = datum.to_iterator(datum.find("string"))) != datum.end()) {
00216           this->AddData(it->second.data());
00217         }
00218         else if ((it = datum.to_iterator(datum.find("vector3"))) != datum.end()) {
00219           D3DXVECTOR3 vector3;
00220           vector3.x = it->second.get<float>("x");
00221           vector3.y = it->second.get<float>("y");
00222           vector3.z = it->second.get<float>("z");
00223           
00224           this->AddData(vector3);
00225         }
00226         else if ((it = datum.to_iterator(datum.find("quat"))) != datum.end()) {
00227           D3DXQUATERNION quat;
00228           quat.x = it->second.get<float>("x");
00229           quat.y = it->second.get<float>("y");
00230           quat.z = it->second.get<float>("z");
00231           quat.w = it->second.get<float>("w");
00232           
00233           this->AddData(quat);
00234         }
00235         else if ((it = datum.to_iterator(datum.find("color"))) != datum.end()) {
00236           D3DXCOLOR color;
00237           color.r = it->second.get<float>("r");
00238           color.g = it->second.get<float>("g");
00239           color.b = it->second.get<float>("b");
00240           color.a = it->second.get<float>("a");
00241           
00242           this->AddData(color);
00243         }
00244         else if ((it = datum.to_iterator(datum.find("envelope"))) != datum.end()) {
00245           EnvelopeSPTR envelope(new Envelope());
00246           
00247           envelope->LoadFromPropertyTree(it->second, "");
00248           
00249           this->AddData(envelope);
00250         }
00251         else  {
00252           LOG(LOG_PRIORITY::INFO, "Deserializing whatever's in the '" + value.first + "' unsupported at this time.");
00253         }
00254       }
00255     }
00256     else  {
00257       LOG(LOG_PRIORITY::INFO, "Deserializing a '" + value.first + "' data item unsupported at this time.");
00258     }
00259   }
00260   
00261 }