#ifndef METHOD_PTRCALL_H #define METHOD_PTRCALL_H #include "typedefs.h" #include "math_2d.h" #include "variant.h" #ifdef PTRCALL_ENABLED template<class T> struct PtrToArg { }; #define MAKE_PTRARG(m_type) \ template<>\ struct PtrToArg<m_type> {\ _FORCE_INLINE_ static m_type convert(const void* p_ptr) {\ return *reinterpret_cast<const m_type*>(p_ptr);\ }\ _FORCE_INLINE_ static void encode(m_type p_val, void* p_ptr) {\ *((m_type*)p_ptr)=p_val;\ }\ };\ template<>\ struct PtrToArg<const m_type&> {\ _FORCE_INLINE_ static m_type convert(const void* p_ptr) {\ return *reinterpret_cast<const m_type*>(p_ptr);\ }\ _FORCE_INLINE_ static void encode(m_type p_val, void* p_ptr) {\ *((m_type*)p_ptr)=p_val;\ }\ } #define MAKE_PTRARGR(m_type,m_ret) \ template<>\ struct PtrToArg<m_type> {\ _FORCE_INLINE_ static m_type convert(const void* p_ptr) {\ return *reinterpret_cast<const m_type*>(p_ptr);\ }\ _FORCE_INLINE_ static void encode(m_type p_val, void* p_ptr) {\ *((m_ret*)p_ptr)=p_val;\ }\ };\ template<>\ struct PtrToArg<const m_type&> {\ _FORCE_INLINE_ static m_type convert(const void* p_ptr) {\ return *reinterpret_cast<const m_type*>(p_ptr);\ }\ _FORCE_INLINE_ static void encode(m_type p_val, void* p_ptr) {\ *((m_ret*)p_ptr)=p_val;\ }\ } MAKE_PTRARG(bool); MAKE_PTRARGR(uint8_t,int); MAKE_PTRARGR(int8_t,int); MAKE_PTRARGR(uint16_t,int); MAKE_PTRARGR(int16_t,int); MAKE_PTRARGR(uint32_t,int); MAKE_PTRARGR(int32_t,int); MAKE_PTRARGR(int64_t,int); MAKE_PTRARGR(uint64_t,int); MAKE_PTRARG(float); MAKE_PTRARGR(double,float); MAKE_PTRARG(String); MAKE_PTRARG(Vector2); MAKE_PTRARG(Rect2); MAKE_PTRARG(Vector3); MAKE_PTRARG(Matrix32); MAKE_PTRARG(Plane); MAKE_PTRARG(Quat); MAKE_PTRARG(AABB); MAKE_PTRARG(Matrix3); MAKE_PTRARG(Transform); MAKE_PTRARG(Color); MAKE_PTRARG(Image); MAKE_PTRARG(NodePath); MAKE_PTRARG(RID); MAKE_PTRARG(InputEvent); MAKE_PTRARG(Dictionary); MAKE_PTRARG(Array); MAKE_PTRARG(ByteArray); MAKE_PTRARG(IntArray); MAKE_PTRARG(RealArray); MAKE_PTRARG(StringArray); MAKE_PTRARG(Vector2Array); MAKE_PTRARG(Vector3Array); MAKE_PTRARG(ColorArray); MAKE_PTRARG(Variant); //this is for Object template<class T> struct PtrToArg< T* > { _FORCE_INLINE_ static T* convert(const void* p_ptr) { return const_cast<T*>(reinterpret_cast<const T*>(p_ptr)); } _FORCE_INLINE_ static void encode(T* p_var, void* p_ptr) { *((T**)p_ptr)=p_var; } }; template<class T> struct PtrToArg< const T* > { _FORCE_INLINE_ static const T* convert(const void* p_ptr) { return reinterpret_cast<const T*>(p_ptr); } _FORCE_INLINE_ static void encode(T* p_var, void* p_ptr) { *((T**)p_ptr)=p_var; } }; //this is for the special cases used by Variant #define MAKE_VECARG(m_type) \ template<>\ struct PtrToArg<Vector<m_type> > {\ _FORCE_INLINE_ static Vector<m_type> convert(const void* p_ptr) {\ const DVector<m_type> *dvs = reinterpret_cast<const DVector<m_type> *>(p_ptr);\ Vector<m_type> ret;\ int len = dvs->size();\ ret.resize(len);\ {\ DVector<m_type>::Read r=dvs->read();\ for(int i=0;i<len;i++) {\ ret[i]=r[i];\ }\ } \ return ret;\ }\ _FORCE_INLINE_ static void encode(Vector<m_type> p_vec, void* p_ptr) {\ DVector<m_type> *dv = reinterpret_cast<DVector<m_type> *>(p_ptr);\ int len=p_vec.size();\ dv->resize(len);\ {\ DVector<m_type>::Write w=dv->write();\ for(int i=0;i<len;i++) {\ w[i]=p_vec[i];\ }\ } \ }\ };\ template<>\ struct PtrToArg<const Vector<m_type>& > {\ _FORCE_INLINE_ static Vector<m_type> convert(const void* p_ptr) {\ const DVector<m_type> *dvs = reinterpret_cast<const DVector<m_type> *>(p_ptr);\ Vector<m_type> ret;\ int len = dvs->size();\ ret.resize(len);\ {\ DVector<m_type>::Read r=dvs->read();\ for(int i=0;i<len;i++) {\ ret[i]=r[i];\ }\ } \ return ret;\ }\ } MAKE_VECARG(String); MAKE_VECARG(uint8_t); MAKE_VECARG(int); MAKE_VECARG(float); MAKE_VECARG(Vector2); MAKE_VECARG(Vector3); MAKE_VECARG(Color); //for stuff that gets converted to Array vectors #define MAKE_VECARR(m_type) \ template<>\ struct PtrToArg<Vector<m_type> > {\ _FORCE_INLINE_ static Vector<m_type> convert(const void* p_ptr) {\ const Array *arr = reinterpret_cast<const Array *>(p_ptr);\ Vector<m_type> ret;\ int len = arr->size();\ ret.resize(len);\ for(int i=0;i<len;i++) {\ ret[i]=(*arr)[i];\ }\ return ret;\ }\ _FORCE_INLINE_ static void encode(Vector<m_type> p_vec, void* p_ptr) {\ Array *arr = reinterpret_cast<Array *>(p_ptr);\ int len = p_vec.size();\ arr->resize(len);\ for(int i=0;i<len;i++) {\ (*arr)[i]=p_vec[i];\ }\ } \ };\ template<>\ struct PtrToArg<const Vector<m_type>& > {\ _FORCE_INLINE_ static Vector<m_type> convert(const void* p_ptr) {\ const Array *arr = reinterpret_cast<const Array *>(p_ptr);\ Vector<m_type> ret;\ int len = arr->size();\ ret.resize(len);\ for(int i=0;i<len;i++) {\ ret[i]=(*arr)[i];\ }\ return ret;\ }\ } MAKE_VECARR(Variant); MAKE_VECARR(RID); MAKE_VECARR(Plane); #define MAKE_DVECARR(m_type) \ template<>\ struct PtrToArg<DVector<m_type> > {\ _FORCE_INLINE_ static DVector<m_type> convert(const void* p_ptr) {\ const Array *arr = reinterpret_cast<const Array *>(p_ptr);\ DVector<m_type> ret;\ int len = arr->size();\ ret.resize(len);\ {\ DVector<m_type>::Write w=ret.write();\ for(int i=0;i<len;i++) {\ w[i]=(*arr)[i];\ }\ }\ return ret;\ }\ _FORCE_INLINE_ static void encode(DVector<m_type> p_vec, void* p_ptr) {\ Array *arr = reinterpret_cast<Array *>(p_ptr);\ int len = p_vec.size();\ arr->resize(len);\ {\ DVector<m_type>::Read r=p_vec.read();\ for(int i=0;i<len;i++) {\ (*arr)[i]=r[i];\ }\ }\ } \ };\ template<>\ struct PtrToArg<const DVector<m_type>& > {\ _FORCE_INLINE_ static DVector<m_type> convert(const void* p_ptr) {\ const Array *arr = reinterpret_cast<const Array *>(p_ptr);\ DVector<m_type> ret;\ int len = arr->size();\ ret.resize(len);\ {\ DVector<m_type>::Write w=ret.write();\ for(int i=0;i<len;i++) {\ w[i]=(*arr)[i];\ }\ }\ return ret;\ }\ } MAKE_DVECARR(Plane); //for special case StringName #define MAKE_STRINGCONV(m_type) \ template<>\ struct PtrToArg<m_type> {\ _FORCE_INLINE_ static m_type convert(const void* p_ptr) {\ m_type s = *reinterpret_cast<const String*>(p_ptr);\ return s;\ }\ _FORCE_INLINE_ static void encode(m_type p_vec, void* p_ptr) {\ String *arr = reinterpret_cast<String *>(p_ptr);\ *arr=p_vec;\ }\ };\ \ template<>\ struct PtrToArg<const m_type&> {\ _FORCE_INLINE_ static m_type convert(const void* p_ptr) {\ m_type s = *reinterpret_cast<const String*>(p_ptr);\ return s;\ }\ } MAKE_STRINGCONV(StringName); MAKE_STRINGCONV(IP_Address); template<> struct PtrToArg<DVector<Face3> > { _FORCE_INLINE_ static DVector<Face3> convert(const void* p_ptr) { const DVector<Vector3> *dvs = reinterpret_cast<const DVector<Vector3> *>(p_ptr); DVector<Face3> ret; int len = dvs->size()/3; ret.resize(len); { DVector<Vector3>::Read r=dvs->read(); DVector<Face3>::Write w=ret.write(); for(int i=0;i<len;i++) { w[i].vertex[0]=r[i*3+0]; w[i].vertex[1]=r[i*3+1]; w[i].vertex[2]=r[i*3+2]; } } return ret; } _FORCE_INLINE_ static void encode(DVector<Face3> p_vec, void* p_ptr) {\ DVector<Vector3> *arr = reinterpret_cast<DVector<Vector3> *>(p_ptr);\ int len = p_vec.size();\ arr->resize(len*3);\ {\ DVector<Face3>::Read r=p_vec.read();\ DVector<Vector3>::Write w=arr->write();\ for(int i=0;i<len;i++) {\ w[i*3+0]=r[i].vertex[0];\ w[i*3+1]=r[i].vertex[1];\ w[i*3+2]=r[i].vertex[2];\ }\ }\ } \ }; template<> struct PtrToArg<const DVector<Face3>& > { _FORCE_INLINE_ static DVector<Face3> convert(const void* p_ptr) { const DVector<Vector3> *dvs = reinterpret_cast<const DVector<Vector3> *>(p_ptr); DVector<Face3> ret; int len = dvs->size()/3; ret.resize(len); { DVector<Vector3>::Read r=dvs->read(); DVector<Face3>::Write w=ret.write(); for(int i=0;i<len;i++) { w[i].vertex[0]=r[i*3+0]; w[i].vertex[1]=r[i*3+1]; w[i].vertex[2]=r[i*3+2]; } } return ret; } }; #endif // METHOD_PTRCALL_H #endif