UGDK
src/ugdk/script/virtualobj.h
Go to the documentation of this file.
00001 
00002 #ifndef UGDK_SCRIPT_VIRTUALOBJ_H_
00003 #define UGDK_SCRIPT_VIRTUALOBJ_H_
00004 
00005 #include <ugdk/script/virtualdata.h>
00006 #include <ugdk/script/type.h>
00007 #include <ugdk/script/langwrapper.h>
00008 #include <ugdk/script/virtualprimitive.h>
00009 #include <ugdk/util/uncopyable.h>
00010 
00011 #include <list>
00012 #include <vector>
00013 #include <map>
00014 #include <string>
00015 
00016 #include <cstdio>
00017 
00018 namespace ugdk {
00019 namespace script {
00020 
00021 class VirtualObj;
00022 class Bind;
00023 class TempList;
00024 
00026 
00031 class VirtualObj {
00032 
00033   public:
00034 
00035     typedef std::pair<VirtualObj,VirtualObj>    VirtualEntry;
00036     typedef std::list<VirtualObj>               List;
00037     typedef std::vector<VirtualObj>             Vector;
00038     typedef std::map<VirtualObj,VirtualObj>     Map;
00039 
00041 
00044     explicit VirtualObj() :
00045         data_() {}
00046 
00047     explicit VirtualObj(VirtualData::Ptr data) :
00048         data_(data) {}
00049 
00050     explicit VirtualObj(LangWrapper* wrapper) :
00051         data_(wrapper->NewData()) {}
00052 
00053     ~VirtualObj() {}
00054 
00055     template <class T>
00056     T value(bool disown = false) const {
00057         return VirtualPrimitive<T>::value(data_, disown);
00058     }
00059 
00060     template <class T>
00061     void set_value(T val) {
00062         VirtualPrimitive<T>::set_value(data_, val);
00063     }
00064 
00065     template <class T>
00066     VirtualObj& operator=(T* obj) {
00067         data_->Wrap(
00068             static_cast<void*>(obj),
00069             TypeRegistry<T>::type()
00070         );
00071         return *this;
00072     }
00073 
00074     LangWrapper* wrapper() const { return data_->wrapper(); }
00075 
00076     bool valid() const { return static_cast<bool>(data_); }
00077 
00078     operator bool() const { return valid(); }
00079 
00080     bool operator<(const VirtualObj& rhs) const {
00081         return data_.get() < rhs.data_.get();
00082     }
00083 
00084     VirtualObj operator() (const List& args = List()) const;
00085 
00086     VirtualObj attribute(const VirtualObj& key) const {
00087         return VirtualObj(data_->GetAttribute(key.data_));
00088     }
00089 
00090     VirtualObj operator[] (const VirtualObj& key) const {
00091         return attribute(key);
00092     }
00093     VirtualObj operator[] (const char* key) const {
00094         return attribute(Create(key, wrapper()));
00095     }
00096     VirtualObj operator[] (const std::string& key) const {
00097         return (*this)[key.c_str()];
00098     }
00099     
00100     VirtualObj set_attribute (const VirtualObj& key, const VirtualObj& value) {
00101         return VirtualObj(
00102             data_->SetAttribute(key.data_, value.data_)
00103         );
00104     }
00105 
00106     TempList operator,(const VirtualObj& rhs) const;
00107 
00108     List& operator,(List& rhs) const {
00109         rhs.push_front(*this);
00110         return rhs;
00111     }
00112 
00113     Bind operator|(const std::string& method_name);
00114 
00115     VirtualObj operator<<(const List& entry) {
00116         List::const_iterator it = entry.begin();
00117         return set_attribute(*(it), *(++it));
00118     }
00119 
00120     template <class T>
00121     static VirtualObj Create (T* obj, LangWrapper* wrapper) {
00122         if (!wrapper) return VirtualObj();
00123         VirtualData::Ptr new_data = wrapper->NewData();
00124         new_data->Wrap(
00125             static_cast<void*>(obj),
00126             TypeRegistry<T>::type()
00127         );
00128         return VirtualObj(new_data);
00129     }
00130 
00131     static VirtualObj Create (const char* obj, LangWrapper* wrapper);
00132 
00133     static VirtualObj Create (const std::string& str, LangWrapper* wrapper) {
00134         return Create(str.c_str(), wrapper);
00135     }
00136     
00137     void* unsafe_data() const {
00138         return data_->unsafe_data();
00139     }
00140 
00141   private:
00142 
00143     VirtualData::Ptr data_;
00144 
00145 };
00146 
00147 template <class T, class U>
00148 T ConvertSequence (const U& data_seq) {
00149     T obj_seq;
00150     typename U::const_iterator it;
00151     for (it = data_seq.begin(); it != data_seq.end(); ++it)
00152         obj_seq.push_back(VirtualObj(*it));
00153     return obj_seq;
00154 }
00155 
00156 /*static bool VObjLess (const VirtualObj& lhs, const VirtualObj& rhs) {
00157     return lhs<rhs;
00158 }*/
00159 
00160 template <class T, class U>
00161 T ConvertTable (const U& data_map) {
00162     T obj_map;
00163     typename U::const_iterator it;
00164     for (it = data_map.begin(); it != data_map.end(); ++it) {
00165         obj_map.insert(std::pair<VirtualObj, VirtualObj>(
00166             VirtualObj(it->first),
00167             VirtualObj(it->second)));
00168     }
00169     return obj_map;
00170 }
00171 
00172 template <>
00173 inline VirtualObj::List VirtualObj::value<VirtualObj::List>(bool disown) const {
00174     return ConvertSequence<List>(data_->UnwrapList());
00175 }
00176 
00177 template <>
00178 inline VirtualObj::Vector VirtualObj::value<VirtualObj::Vector>(bool disown) const {
00179     return ConvertSequence<Vector>(data_->UnwrapVector());
00180 }
00181 
00182 template <>
00183 inline VirtualObj::Map VirtualObj::value<VirtualObj::Map>(bool disown) const {
00184     return ConvertTable<Map>(data_->UnwrapMap());
00185 }
00186 
00187 class Bind {
00188   public:
00189     Bind(VirtualObj& obj, const std::string& method_name) :
00190         obj_(obj),
00191         method_name_(obj.wrapper()) {
00192         method_name_.set_value(method_name.c_str());
00193     }
00194     VirtualObj operator() () const {
00195         std::list<VirtualObj> args;
00196         return obj_[method_name_]((obj_, args)); 
00197     }
00198     VirtualObj operator() (std::list<VirtualObj>& args) const {
00199         return obj_[method_name_]((obj_, args));
00200     }
00201   private:
00202     Bind& operator=(Bind&); // Bind cannot be copied.
00203 
00204     VirtualObj&   obj_;
00205     VirtualObj    method_name_;
00206 };
00207 
00208 class TempList {
00209   public:
00210     operator VirtualObj::List&() { return l_; }
00211     TempList& operator,(const VirtualObj& rhs) {
00212         l_.push_back(rhs);
00213         return *this;
00214     }
00215   private:
00216     friend class VirtualObj;
00217     TempList(const VirtualObj& first, const VirtualObj& second) :
00218         l_() {
00219         l_.push_back(first);
00220         l_.push_back(second);
00221     }
00222     VirtualObj::List l_;
00223 };
00224 
00225 inline TempList VirtualObj::operator,(const VirtualObj& rhs) const {
00226     return TempList(*this, rhs);
00227 }
00228 
00229 inline Bind VirtualObj::operator|(const std::string& method_name) {
00230     Bind result(*this, method_name);
00231     return result;
00232 }
00233 
00234 } /* namespace script */
00235 } /* namespace ugdk */
00236 
00237 #endif /* UGDK_SCRIPT_VIRTUALOBJ_H_ */
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines