UGDK
|
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_ */