initial commit
This commit is contained in:
commit
3d7202a915
|
@ -0,0 +1,581 @@
|
|||
#ifndef AS_GEN_WRAPPER_H
|
||||
#define AS_GEN_WRAPPER_H
|
||||
|
||||
#ifndef ANGELSCRIPT_H
|
||||
// Avoid having to inform include path if header is already include before
|
||||
#include <angelscript.h>
|
||||
#endif
|
||||
|
||||
#include <new>
|
||||
|
||||
namespace gw {
|
||||
|
||||
template <typename T> class Proxy {
|
||||
public:
|
||||
T value;
|
||||
Proxy(T value) : value(value) {}
|
||||
static T cast(void * ptr) {
|
||||
return reinterpret_cast<Proxy<T> *>(&ptr)->value;
|
||||
}
|
||||
private:
|
||||
Proxy(const Proxy &);
|
||||
Proxy & operator=(const Proxy &);
|
||||
};
|
||||
|
||||
template <typename T> struct Wrapper {};
|
||||
template <typename T> struct ObjFirst {};
|
||||
template <typename T> struct ObjLast {};
|
||||
template <typename T> struct Constructor {};
|
||||
|
||||
template <typename T>
|
||||
void destroy(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {
|
||||
static_cast<T *>(gen->GetObject())->~T();
|
||||
}
|
||||
template <>
|
||||
struct Wrapper<void (*)(void)> {
|
||||
template <void (*fp)(void)>
|
||||
static void f(AS_NAMESPACE_QUALIFIER asIScriptGeneric * /*gen*/) {
|
||||
((fp)());
|
||||
}
|
||||
};
|
||||
template <typename R>
|
||||
struct Wrapper<R (*)(void)> {
|
||||
template <R (*fp)(void)>
|
||||
static void f(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {
|
||||
new (gen->GetAddressOfReturnLocation()) Proxy<R>((fp)());
|
||||
}
|
||||
};
|
||||
template <typename T>
|
||||
struct Wrapper<void (T::*)(void)> {
|
||||
template <void (T::*fp)(void)>
|
||||
static void f(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {
|
||||
((static_cast<T *>(gen->GetObject())->*fp)());
|
||||
}
|
||||
};
|
||||
template <typename T, typename R>
|
||||
struct Wrapper<R (T::*)(void)> {
|
||||
template <R (T::*fp)(void)>
|
||||
static void f(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {
|
||||
new (gen->GetAddressOfReturnLocation()) Proxy<R>((static_cast<T *>(gen->GetObject())->*fp)());
|
||||
}
|
||||
};
|
||||
template <typename T>
|
||||
struct Wrapper<void (T::*)(void) const> {
|
||||
template <void (T::*fp)(void) const>
|
||||
static void f(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {
|
||||
((static_cast<T *>(gen->GetObject())->*fp)());
|
||||
}
|
||||
};
|
||||
template <typename T, typename R>
|
||||
struct Wrapper<R (T::*)(void) const> {
|
||||
template <R (T::*fp)(void) const>
|
||||
static void f(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {
|
||||
new (gen->GetAddressOfReturnLocation()) Proxy<R>((static_cast<T *>(gen->GetObject())->*fp)());
|
||||
}
|
||||
};
|
||||
template <typename T>
|
||||
struct ObjFirst<void (*)(T)> {
|
||||
template <void (*fp)(T)>
|
||||
static void f(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {
|
||||
((fp)(
|
||||
Proxy<T>::cast(gen->GetObject())));
|
||||
}
|
||||
};
|
||||
template <typename T, typename R>
|
||||
struct ObjFirst<R (*)(T)> {
|
||||
template <R (*fp)(T)>
|
||||
static void f(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {
|
||||
new (gen->GetAddressOfReturnLocation()) Proxy<R>((fp)(
|
||||
Proxy<T>::cast(gen->GetObject())));
|
||||
}
|
||||
};
|
||||
template <typename T>
|
||||
struct ObjLast<void (*)(T)> {
|
||||
template <void (*fp)(T)>
|
||||
static void f(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {
|
||||
((fp)(
|
||||
Proxy<T>::cast(gen->GetObject())));
|
||||
}
|
||||
};
|
||||
template <typename T, typename R>
|
||||
struct ObjLast<R (*)(T)> {
|
||||
template <R (*fp)(T)>
|
||||
static void f(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {
|
||||
new (gen->GetAddressOfReturnLocation()) Proxy<R>((fp)(
|
||||
Proxy<T>::cast(gen->GetObject())));
|
||||
}
|
||||
};
|
||||
template <typename T>
|
||||
struct Constructor <T ()> {
|
||||
static void f(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {
|
||||
new (gen->GetObject()) T();
|
||||
}
|
||||
};
|
||||
template <typename A0>
|
||||
struct Wrapper<void (*)(A0)> {
|
||||
template <void (*fp)(A0)>
|
||||
static void f(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {
|
||||
((fp)(
|
||||
static_cast<Proxy <A0> *>(gen->GetAddressOfArg(0))->value));
|
||||
}
|
||||
};
|
||||
template <typename R, typename A0>
|
||||
struct Wrapper<R (*)(A0)> {
|
||||
template <R (*fp)(A0)>
|
||||
static void f(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {
|
||||
new (gen->GetAddressOfReturnLocation()) Proxy<R>((fp)(
|
||||
static_cast<Proxy <A0> *>(gen->GetAddressOfArg(0))->value));
|
||||
}
|
||||
};
|
||||
template <typename T, typename A0>
|
||||
struct Wrapper<void (T::*)(A0)> {
|
||||
template <void (T::*fp)(A0)>
|
||||
static void f(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {
|
||||
((static_cast<T *>(gen->GetObject())->*fp)(
|
||||
static_cast<Proxy <A0> *>(gen->GetAddressOfArg(0))->value));
|
||||
}
|
||||
};
|
||||
template <typename T, typename R, typename A0>
|
||||
struct Wrapper<R (T::*)(A0)> {
|
||||
template <R (T::*fp)(A0)>
|
||||
static void f(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {
|
||||
new (gen->GetAddressOfReturnLocation()) Proxy<R>((static_cast<T *>(gen->GetObject())->*fp)(
|
||||
static_cast<Proxy <A0> *>(gen->GetAddressOfArg(0))->value));
|
||||
}
|
||||
};
|
||||
template <typename T, typename A0>
|
||||
struct Wrapper<void (T::*)(A0) const> {
|
||||
template <void (T::*fp)(A0) const>
|
||||
static void f(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {
|
||||
((static_cast<T *>(gen->GetObject())->*fp)(
|
||||
static_cast<Proxy <A0> *>(gen->GetAddressOfArg(0))->value));
|
||||
}
|
||||
};
|
||||
template <typename T, typename R, typename A0>
|
||||
struct Wrapper<R (T::*)(A0) const> {
|
||||
template <R (T::*fp)(A0) const>
|
||||
static void f(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {
|
||||
new (gen->GetAddressOfReturnLocation()) Proxy<R>((static_cast<T *>(gen->GetObject())->*fp)(
|
||||
static_cast<Proxy <A0> *>(gen->GetAddressOfArg(0))->value));
|
||||
}
|
||||
};
|
||||
template <typename T, typename A0>
|
||||
struct ObjFirst<void (*)(T, A0)> {
|
||||
template <void (*fp)(T, A0)>
|
||||
static void f(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {
|
||||
((fp)(
|
||||
Proxy<T>::cast(gen->GetObject()),
|
||||
static_cast<Proxy <A0> *>(gen->GetAddressOfArg(0))->value));
|
||||
}
|
||||
};
|
||||
template <typename T, typename R, typename A0>
|
||||
struct ObjFirst<R (*)(T, A0)> {
|
||||
template <R (*fp)(T, A0)>
|
||||
static void f(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {
|
||||
new (gen->GetAddressOfReturnLocation()) Proxy<R>((fp)(
|
||||
Proxy<T>::cast(gen->GetObject()),
|
||||
static_cast<Proxy <A0> *>(gen->GetAddressOfArg(0))->value));
|
||||
}
|
||||
};
|
||||
template <typename T, typename A0>
|
||||
struct ObjLast<void (*)(A0, T)> {
|
||||
template <void (*fp)(A0, T)>
|
||||
static void f(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {
|
||||
((fp)(
|
||||
static_cast<Proxy <A0> *>(gen->GetAddressOfArg(0))->value,
|
||||
Proxy<T>::cast(gen->GetObject())));
|
||||
}
|
||||
};
|
||||
template <typename T, typename R, typename A0>
|
||||
struct ObjLast<R (*)(A0, T)> {
|
||||
template <R (*fp)(A0, T)>
|
||||
static void f(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {
|
||||
new (gen->GetAddressOfReturnLocation()) Proxy<R>((fp)(
|
||||
static_cast<Proxy <A0> *>(gen->GetAddressOfArg(0))->value,
|
||||
Proxy<T>::cast(gen->GetObject())));
|
||||
}
|
||||
};
|
||||
template <typename T, typename A0>
|
||||
struct Constructor <T (A0)> {
|
||||
static void f(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {
|
||||
new (gen->GetObject()) T(
|
||||
static_cast<Proxy <A0> *>(gen->GetAddressOfArg(0))->value);
|
||||
}
|
||||
};
|
||||
template <typename A0, typename A1>
|
||||
struct Wrapper<void (*)(A0, A1)> {
|
||||
template <void (*fp)(A0, A1)>
|
||||
static void f(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {
|
||||
((fp)(
|
||||
static_cast<Proxy <A0> *>(gen->GetAddressOfArg(0))->value,
|
||||
static_cast<Proxy <A1> *>(gen->GetAddressOfArg(1))->value));
|
||||
}
|
||||
};
|
||||
template <typename R, typename A0, typename A1>
|
||||
struct Wrapper<R (*)(A0, A1)> {
|
||||
template <R (*fp)(A0, A1)>
|
||||
static void f(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {
|
||||
new (gen->GetAddressOfReturnLocation()) Proxy<R>((fp)(
|
||||
static_cast<Proxy <A0> *>(gen->GetAddressOfArg(0))->value,
|
||||
static_cast<Proxy <A1> *>(gen->GetAddressOfArg(1))->value));
|
||||
}
|
||||
};
|
||||
template <typename T, typename A0, typename A1>
|
||||
struct Wrapper<void (T::*)(A0, A1)> {
|
||||
template <void (T::*fp)(A0, A1)>
|
||||
static void f(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {
|
||||
((static_cast<T *>(gen->GetObject())->*fp)(
|
||||
static_cast<Proxy <A0> *>(gen->GetAddressOfArg(0))->value,
|
||||
static_cast<Proxy <A1> *>(gen->GetAddressOfArg(1))->value));
|
||||
}
|
||||
};
|
||||
template <typename T, typename R, typename A0, typename A1>
|
||||
struct Wrapper<R (T::*)(A0, A1)> {
|
||||
template <R (T::*fp)(A0, A1)>
|
||||
static void f(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {
|
||||
new (gen->GetAddressOfReturnLocation()) Proxy<R>((static_cast<T *>(gen->GetObject())->*fp)(
|
||||
static_cast<Proxy <A0> *>(gen->GetAddressOfArg(0))->value,
|
||||
static_cast<Proxy <A1> *>(gen->GetAddressOfArg(1))->value));
|
||||
}
|
||||
};
|
||||
template <typename T, typename A0, typename A1>
|
||||
struct Wrapper<void (T::*)(A0, A1) const> {
|
||||
template <void (T::*fp)(A0, A1) const>
|
||||
static void f(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {
|
||||
((static_cast<T *>(gen->GetObject())->*fp)(
|
||||
static_cast<Proxy <A0> *>(gen->GetAddressOfArg(0))->value,
|
||||
static_cast<Proxy <A1> *>(gen->GetAddressOfArg(1))->value));
|
||||
}
|
||||
};
|
||||
template <typename T, typename R, typename A0, typename A1>
|
||||
struct Wrapper<R (T::*)(A0, A1) const> {
|
||||
template <R (T::*fp)(A0, A1) const>
|
||||
static void f(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {
|
||||
new (gen->GetAddressOfReturnLocation()) Proxy<R>((static_cast<T *>(gen->GetObject())->*fp)(
|
||||
static_cast<Proxy <A0> *>(gen->GetAddressOfArg(0))->value,
|
||||
static_cast<Proxy <A1> *>(gen->GetAddressOfArg(1))->value));
|
||||
}
|
||||
};
|
||||
template <typename T, typename A0, typename A1>
|
||||
struct ObjFirst<void (*)(T, A0, A1)> {
|
||||
template <void (*fp)(T, A0, A1)>
|
||||
static void f(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {
|
||||
((fp)(
|
||||
Proxy<T>::cast(gen->GetObject()),
|
||||
static_cast<Proxy <A0> *>(gen->GetAddressOfArg(0))->value,
|
||||
static_cast<Proxy <A1> *>(gen->GetAddressOfArg(1))->value));
|
||||
}
|
||||
};
|
||||
template <typename T, typename R, typename A0, typename A1>
|
||||
struct ObjFirst<R (*)(T, A0, A1)> {
|
||||
template <R (*fp)(T, A0, A1)>
|
||||
static void f(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {
|
||||
new (gen->GetAddressOfReturnLocation()) Proxy<R>((fp)(
|
||||
Proxy<T>::cast(gen->GetObject()),
|
||||
static_cast<Proxy <A0> *>(gen->GetAddressOfArg(0))->value,
|
||||
static_cast<Proxy <A1> *>(gen->GetAddressOfArg(1))->value));
|
||||
}
|
||||
};
|
||||
template <typename T, typename A0, typename A1>
|
||||
struct ObjLast<void (*)(A0, A1, T)> {
|
||||
template <void (*fp)(A0, A1, T)>
|
||||
static void f(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {
|
||||
((fp)(
|
||||
static_cast<Proxy <A0> *>(gen->GetAddressOfArg(0))->value,
|
||||
static_cast<Proxy <A1> *>(gen->GetAddressOfArg(1))->value,
|
||||
Proxy<T>::cast(gen->GetObject())));
|
||||
}
|
||||
};
|
||||
template <typename T, typename R, typename A0, typename A1>
|
||||
struct ObjLast<R (*)(A0, A1, T)> {
|
||||
template <R (*fp)(A0, A1, T)>
|
||||
static void f(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {
|
||||
new (gen->GetAddressOfReturnLocation()) Proxy<R>((fp)(
|
||||
static_cast<Proxy <A0> *>(gen->GetAddressOfArg(0))->value,
|
||||
static_cast<Proxy <A1> *>(gen->GetAddressOfArg(1))->value,
|
||||
Proxy<T>::cast(gen->GetObject())));
|
||||
}
|
||||
};
|
||||
template <typename T, typename A0, typename A1>
|
||||
struct Constructor <T (A0, A1)> {
|
||||
static void f(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {
|
||||
new (gen->GetObject()) T(
|
||||
static_cast<Proxy <A0> *>(gen->GetAddressOfArg(0))->value,
|
||||
static_cast<Proxy <A1> *>(gen->GetAddressOfArg(1))->value);
|
||||
}
|
||||
};
|
||||
template <typename A0, typename A1, typename A2>
|
||||
struct Wrapper<void (*)(A0, A1, A2)> {
|
||||
template <void (*fp)(A0, A1, A2)>
|
||||
static void f(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {
|
||||
((fp)(
|
||||
static_cast<Proxy <A0> *>(gen->GetAddressOfArg(0))->value,
|
||||
static_cast<Proxy <A1> *>(gen->GetAddressOfArg(1))->value,
|
||||
static_cast<Proxy <A2> *>(gen->GetAddressOfArg(2))->value));
|
||||
}
|
||||
};
|
||||
template <typename R, typename A0, typename A1, typename A2>
|
||||
struct Wrapper<R (*)(A0, A1, A2)> {
|
||||
template <R (*fp)(A0, A1, A2)>
|
||||
static void f(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {
|
||||
new (gen->GetAddressOfReturnLocation()) Proxy<R>((fp)(
|
||||
static_cast<Proxy <A0> *>(gen->GetAddressOfArg(0))->value,
|
||||
static_cast<Proxy <A1> *>(gen->GetAddressOfArg(1))->value,
|
||||
static_cast<Proxy <A2> *>(gen->GetAddressOfArg(2))->value));
|
||||
}
|
||||
};
|
||||
template <typename T, typename A0, typename A1, typename A2>
|
||||
struct Wrapper<void (T::*)(A0, A1, A2)> {
|
||||
template <void (T::*fp)(A0, A1, A2)>
|
||||
static void f(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {
|
||||
((static_cast<T *>(gen->GetObject())->*fp)(
|
||||
static_cast<Proxy <A0> *>(gen->GetAddressOfArg(0))->value,
|
||||
static_cast<Proxy <A1> *>(gen->GetAddressOfArg(1))->value,
|
||||
static_cast<Proxy <A2> *>(gen->GetAddressOfArg(2))->value));
|
||||
}
|
||||
};
|
||||
template <typename T, typename R, typename A0, typename A1, typename A2>
|
||||
struct Wrapper<R (T::*)(A0, A1, A2)> {
|
||||
template <R (T::*fp)(A0, A1, A2)>
|
||||
static void f(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {
|
||||
new (gen->GetAddressOfReturnLocation()) Proxy<R>((static_cast<T *>(gen->GetObject())->*fp)(
|
||||
static_cast<Proxy <A0> *>(gen->GetAddressOfArg(0))->value,
|
||||
static_cast<Proxy <A1> *>(gen->GetAddressOfArg(1))->value,
|
||||
static_cast<Proxy <A2> *>(gen->GetAddressOfArg(2))->value));
|
||||
}
|
||||
};
|
||||
template <typename T, typename A0, typename A1, typename A2>
|
||||
struct Wrapper<void (T::*)(A0, A1, A2) const> {
|
||||
template <void (T::*fp)(A0, A1, A2) const>
|
||||
static void f(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {
|
||||
((static_cast<T *>(gen->GetObject())->*fp)(
|
||||
static_cast<Proxy <A0> *>(gen->GetAddressOfArg(0))->value,
|
||||
static_cast<Proxy <A1> *>(gen->GetAddressOfArg(1))->value,
|
||||
static_cast<Proxy <A2> *>(gen->GetAddressOfArg(2))->value));
|
||||
}
|
||||
};
|
||||
template <typename T, typename R, typename A0, typename A1, typename A2>
|
||||
struct Wrapper<R (T::*)(A0, A1, A2) const> {
|
||||
template <R (T::*fp)(A0, A1, A2) const>
|
||||
static void f(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {
|
||||
new (gen->GetAddressOfReturnLocation()) Proxy<R>((static_cast<T *>(gen->GetObject())->*fp)(
|
||||
static_cast<Proxy <A0> *>(gen->GetAddressOfArg(0))->value,
|
||||
static_cast<Proxy <A1> *>(gen->GetAddressOfArg(1))->value,
|
||||
static_cast<Proxy <A2> *>(gen->GetAddressOfArg(2))->value));
|
||||
}
|
||||
};
|
||||
template <typename T, typename A0, typename A1, typename A2>
|
||||
struct ObjFirst<void (*)(T, A0, A1, A2)> {
|
||||
template <void (*fp)(T, A0, A1, A2)>
|
||||
static void f(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {
|
||||
((fp)(
|
||||
Proxy<T>::cast(gen->GetObject()),
|
||||
static_cast<Proxy <A0> *>(gen->GetAddressOfArg(0))->value,
|
||||
static_cast<Proxy <A1> *>(gen->GetAddressOfArg(1))->value,
|
||||
static_cast<Proxy <A2> *>(gen->GetAddressOfArg(2))->value));
|
||||
}
|
||||
};
|
||||
template <typename T, typename R, typename A0, typename A1, typename A2>
|
||||
struct ObjFirst<R (*)(T, A0, A1, A2)> {
|
||||
template <R (*fp)(T, A0, A1, A2)>
|
||||
static void f(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {
|
||||
new (gen->GetAddressOfReturnLocation()) Proxy<R>((fp)(
|
||||
Proxy<T>::cast(gen->GetObject()),
|
||||
static_cast<Proxy <A0> *>(gen->GetAddressOfArg(0))->value,
|
||||
static_cast<Proxy <A1> *>(gen->GetAddressOfArg(1))->value,
|
||||
static_cast<Proxy <A2> *>(gen->GetAddressOfArg(2))->value));
|
||||
}
|
||||
};
|
||||
template <typename T, typename A0, typename A1, typename A2>
|
||||
struct ObjLast<void (*)(A0, A1, A2, T)> {
|
||||
template <void (*fp)(A0, A1, A2, T)>
|
||||
static void f(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {
|
||||
((fp)(
|
||||
static_cast<Proxy <A0> *>(gen->GetAddressOfArg(0))->value,
|
||||
static_cast<Proxy <A1> *>(gen->GetAddressOfArg(1))->value,
|
||||
static_cast<Proxy <A2> *>(gen->GetAddressOfArg(2))->value,
|
||||
Proxy<T>::cast(gen->GetObject())));
|
||||
}
|
||||
};
|
||||
template <typename T, typename R, typename A0, typename A1, typename A2>
|
||||
struct ObjLast<R (*)(A0, A1, A2, T)> {
|
||||
template <R (*fp)(A0, A1, A2, T)>
|
||||
static void f(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {
|
||||
new (gen->GetAddressOfReturnLocation()) Proxy<R>((fp)(
|
||||
static_cast<Proxy <A0> *>(gen->GetAddressOfArg(0))->value,
|
||||
static_cast<Proxy <A1> *>(gen->GetAddressOfArg(1))->value,
|
||||
static_cast<Proxy <A2> *>(gen->GetAddressOfArg(2))->value,
|
||||
Proxy<T>::cast(gen->GetObject())));
|
||||
}
|
||||
};
|
||||
template <typename T, typename A0, typename A1, typename A2>
|
||||
struct Constructor <T (A0, A1, A2)> {
|
||||
static void f(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {
|
||||
new (gen->GetObject()) T(
|
||||
static_cast<Proxy <A0> *>(gen->GetAddressOfArg(0))->value,
|
||||
static_cast<Proxy <A1> *>(gen->GetAddressOfArg(1))->value,
|
||||
static_cast<Proxy <A2> *>(gen->GetAddressOfArg(2))->value);
|
||||
}
|
||||
};
|
||||
template <typename A0, typename A1, typename A2, typename A3>
|
||||
struct Wrapper<void (*)(A0, A1, A2, A3)> {
|
||||
template <void (*fp)(A0, A1, A2, A3)>
|
||||
static void f(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {
|
||||
((fp)(
|
||||
static_cast<Proxy <A0> *>(gen->GetAddressOfArg(0))->value,
|
||||
static_cast<Proxy <A1> *>(gen->GetAddressOfArg(1))->value,
|
||||
static_cast<Proxy <A2> *>(gen->GetAddressOfArg(2))->value,
|
||||
static_cast<Proxy <A3> *>(gen->GetAddressOfArg(3))->value));
|
||||
}
|
||||
};
|
||||
template <typename R, typename A0, typename A1, typename A2, typename A3>
|
||||
struct Wrapper<R (*)(A0, A1, A2, A3)> {
|
||||
template <R (*fp)(A0, A1, A2, A3)>
|
||||
static void f(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {
|
||||
new (gen->GetAddressOfReturnLocation()) Proxy<R>((fp)(
|
||||
static_cast<Proxy <A0> *>(gen->GetAddressOfArg(0))->value,
|
||||
static_cast<Proxy <A1> *>(gen->GetAddressOfArg(1))->value,
|
||||
static_cast<Proxy <A2> *>(gen->GetAddressOfArg(2))->value,
|
||||
static_cast<Proxy <A3> *>(gen->GetAddressOfArg(3))->value));
|
||||
}
|
||||
};
|
||||
template <typename T, typename A0, typename A1, typename A2, typename A3>
|
||||
struct Wrapper<void (T::*)(A0, A1, A2, A3)> {
|
||||
template <void (T::*fp)(A0, A1, A2, A3)>
|
||||
static void f(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {
|
||||
((static_cast<T *>(gen->GetObject())->*fp)(
|
||||
static_cast<Proxy <A0> *>(gen->GetAddressOfArg(0))->value,
|
||||
static_cast<Proxy <A1> *>(gen->GetAddressOfArg(1))->value,
|
||||
static_cast<Proxy <A2> *>(gen->GetAddressOfArg(2))->value,
|
||||
static_cast<Proxy <A3> *>(gen->GetAddressOfArg(3))->value));
|
||||
}
|
||||
};
|
||||
template <typename T, typename R, typename A0, typename A1, typename A2, typename A3>
|
||||
struct Wrapper<R (T::*)(A0, A1, A2, A3)> {
|
||||
template <R (T::*fp)(A0, A1, A2, A3)>
|
||||
static void f(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {
|
||||
new (gen->GetAddressOfReturnLocation()) Proxy<R>((static_cast<T *>(gen->GetObject())->*fp)(
|
||||
static_cast<Proxy <A0> *>(gen->GetAddressOfArg(0))->value,
|
||||
static_cast<Proxy <A1> *>(gen->GetAddressOfArg(1))->value,
|
||||
static_cast<Proxy <A2> *>(gen->GetAddressOfArg(2))->value,
|
||||
static_cast<Proxy <A3> *>(gen->GetAddressOfArg(3))->value));
|
||||
}
|
||||
};
|
||||
template <typename T, typename A0, typename A1, typename A2, typename A3>
|
||||
struct Wrapper<void (T::*)(A0, A1, A2, A3) const> {
|
||||
template <void (T::*fp)(A0, A1, A2, A3) const>
|
||||
static void f(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {
|
||||
((static_cast<T *>(gen->GetObject())->*fp)(
|
||||
static_cast<Proxy <A0> *>(gen->GetAddressOfArg(0))->value,
|
||||
static_cast<Proxy <A1> *>(gen->GetAddressOfArg(1))->value,
|
||||
static_cast<Proxy <A2> *>(gen->GetAddressOfArg(2))->value,
|
||||
static_cast<Proxy <A3> *>(gen->GetAddressOfArg(3))->value));
|
||||
}
|
||||
};
|
||||
template <typename T, typename R, typename A0, typename A1, typename A2, typename A3>
|
||||
struct Wrapper<R (T::*)(A0, A1, A2, A3) const> {
|
||||
template <R (T::*fp)(A0, A1, A2, A3) const>
|
||||
static void f(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {
|
||||
new (gen->GetAddressOfReturnLocation()) Proxy<R>((static_cast<T *>(gen->GetObject())->*fp)(
|
||||
static_cast<Proxy <A0> *>(gen->GetAddressOfArg(0))->value,
|
||||
static_cast<Proxy <A1> *>(gen->GetAddressOfArg(1))->value,
|
||||
static_cast<Proxy <A2> *>(gen->GetAddressOfArg(2))->value,
|
||||
static_cast<Proxy <A3> *>(gen->GetAddressOfArg(3))->value));
|
||||
}
|
||||
};
|
||||
template <typename T, typename A0, typename A1, typename A2, typename A3>
|
||||
struct ObjFirst<void (*)(T, A0, A1, A2, A3)> {
|
||||
template <void (*fp)(T, A0, A1, A2, A3)>
|
||||
static void f(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {
|
||||
((fp)(
|
||||
Proxy<T>::cast(gen->GetObject()),
|
||||
static_cast<Proxy <A0> *>(gen->GetAddressOfArg(0))->value,
|
||||
static_cast<Proxy <A1> *>(gen->GetAddressOfArg(1))->value,
|
||||
static_cast<Proxy <A2> *>(gen->GetAddressOfArg(2))->value,
|
||||
static_cast<Proxy <A3> *>(gen->GetAddressOfArg(3))->value));
|
||||
}
|
||||
};
|
||||
template <typename T, typename R, typename A0, typename A1, typename A2, typename A3>
|
||||
struct ObjFirst<R (*)(T, A0, A1, A2, A3)> {
|
||||
template <R (*fp)(T, A0, A1, A2, A3)>
|
||||
static void f(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {
|
||||
new (gen->GetAddressOfReturnLocation()) Proxy<R>((fp)(
|
||||
Proxy<T>::cast(gen->GetObject()),
|
||||
static_cast<Proxy <A0> *>(gen->GetAddressOfArg(0))->value,
|
||||
static_cast<Proxy <A1> *>(gen->GetAddressOfArg(1))->value,
|
||||
static_cast<Proxy <A2> *>(gen->GetAddressOfArg(2))->value,
|
||||
static_cast<Proxy <A3> *>(gen->GetAddressOfArg(3))->value));
|
||||
}
|
||||
};
|
||||
template <typename T, typename A0, typename A1, typename A2, typename A3>
|
||||
struct ObjLast<void (*)(A0, A1, A2, A3, T)> {
|
||||
template <void (*fp)(A0, A1, A2, A3, T)>
|
||||
static void f(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {
|
||||
((fp)(
|
||||
static_cast<Proxy <A0> *>(gen->GetAddressOfArg(0))->value,
|
||||
static_cast<Proxy <A1> *>(gen->GetAddressOfArg(1))->value,
|
||||
static_cast<Proxy <A2> *>(gen->GetAddressOfArg(2))->value,
|
||||
static_cast<Proxy <A3> *>(gen->GetAddressOfArg(3))->value,
|
||||
Proxy<T>::cast(gen->GetObject())));
|
||||
}
|
||||
};
|
||||
template <typename T, typename R, typename A0, typename A1, typename A2, typename A3>
|
||||
struct ObjLast<R (*)(A0, A1, A2, A3, T)> {
|
||||
template <R (*fp)(A0, A1, A2, A3, T)>
|
||||
static void f(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {
|
||||
new (gen->GetAddressOfReturnLocation()) Proxy<R>((fp)(
|
||||
static_cast<Proxy <A0> *>(gen->GetAddressOfArg(0))->value,
|
||||
static_cast<Proxy <A1> *>(gen->GetAddressOfArg(1))->value,
|
||||
static_cast<Proxy <A2> *>(gen->GetAddressOfArg(2))->value,
|
||||
static_cast<Proxy <A3> *>(gen->GetAddressOfArg(3))->value,
|
||||
Proxy<T>::cast(gen->GetObject())));
|
||||
}
|
||||
};
|
||||
template <typename T, typename A0, typename A1, typename A2, typename A3>
|
||||
struct Constructor <T (A0, A1, A2, A3)> {
|
||||
static void f(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {
|
||||
new (gen->GetObject()) T(
|
||||
static_cast<Proxy <A0> *>(gen->GetAddressOfArg(0))->value,
|
||||
static_cast<Proxy <A1> *>(gen->GetAddressOfArg(1))->value,
|
||||
static_cast<Proxy <A2> *>(gen->GetAddressOfArg(2))->value,
|
||||
static_cast<Proxy <A3> *>(gen->GetAddressOfArg(3))->value);
|
||||
}
|
||||
};
|
||||
template <typename T>
|
||||
struct Id {
|
||||
template <T fn_ptr> AS_NAMESPACE_QUALIFIER asSFuncPtr f(void) { return asFUNCTION(&Wrapper<T>::template f<fn_ptr>); }
|
||||
template <T fn_ptr> AS_NAMESPACE_QUALIFIER asSFuncPtr of(void) { return asFUNCTION(&ObjFirst<T>::template f<fn_ptr>); }
|
||||
template <T fn_ptr> AS_NAMESPACE_QUALIFIER asSFuncPtr ol(void) { return asFUNCTION(&ObjLast<T>::template f<fn_ptr>); }
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
Id<T> id(T /*fn_ptr*/) { return Id<T>(); }
|
||||
|
||||
// On some versions of GNUC it is necessary to use the template keyword as disambiguator,
|
||||
// on others the template keyword gives an error, hence the need for the following define.
|
||||
// MSVC on the other hand seems to accept both with or without the template keyword.
|
||||
#if defined(__GNUC__) && (__GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 4))
|
||||
// GNUC 4.4.3 doesn't need the template keyword, and
|
||||
// hopefully upcoming versions won't need it either
|
||||
#define TMPL template
|
||||
#else
|
||||
#define TMPL
|
||||
#endif
|
||||
|
||||
#define WRAP_FN(name) (::gw::id(name).TMPL f< name >())
|
||||
#define WRAP_MFN(ClassType, name) (::gw::id(&ClassType::name).TMPL f< &ClassType::name >())
|
||||
#define WRAP_OBJ_FIRST(name) (::gw::id(name).TMPL of< name >())
|
||||
#define WRAP_OBJ_LAST(name) (::gw::id(name).TMPL ol< name >())
|
||||
|
||||
#define WRAP_FN_PR(name, Parameters, ReturnType) asFUNCTION((::gw::Wrapper<ReturnType (*)Parameters>::TMPL f< name >))
|
||||
#define WRAP_MFN_PR(ClassType, name, Parameters, ReturnType) asFUNCTION((::gw::Wrapper<ReturnType (ClassType::*)Parameters>::TMPL f< &ClassType::name >))
|
||||
#define WRAP_OBJ_FIRST_PR(name, Parameters, ReturnType) asFUNCTION((::gw::ObjFirst<ReturnType (*)Parameters>::TMPL f< name >))
|
||||
#define WRAP_OBJ_LAST_PR(name, Parameters, ReturnType) asFUNCTION((::gw::ObjLast<ReturnType (*)Parameters>::TMPL f< name >))
|
||||
|
||||
#define WRAP_CON(ClassType, Parameters) asFUNCTION((::gw::Constructor<ClassType Parameters>::f))
|
||||
#define WRAP_DES(ClassType) asFUNCTION((::gw::destroy<ClassType>))
|
||||
|
||||
|
||||
} // end namespace gw
|
||||
|
||||
#endif
|
|
@ -0,0 +1,166 @@
|
|||
//
|
||||
// This generator creates a header file that implements automatic
|
||||
// wrapper functions for the generic calling convention.
|
||||
//
|
||||
// Originally implemented by George Yohng from 4Front Technologies in 2009-03-11
|
||||
// Modifications by Pierre Fortin in order to add constructor wrapper generation
|
||||
//
|
||||
// A completely new implementation of automatic wrapper functions was
|
||||
// implemented by SiCrane at GameDev.net in 2011-12-18. The generator was
|
||||
// adapted from Python to C++ by Andreas.
|
||||
//
|
||||
// ref: http://www.gamedev.net/topic/617111-more-angelscript-binding-wrappers/
|
||||
//
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string>
|
||||
|
||||
// Generate templates for up to this number of function parameters
|
||||
const int max_args = 4;
|
||||
|
||||
using namespace std;
|
||||
|
||||
void PrintTemplate(const char *base, const char *typeNameList, const char *retType, const char *objType, const char *isConst, const char *newExpr, const char *objExpr, const char *argList1, const char *argList2, const char *wrapName);
|
||||
void PrintConstructor(const char *comma, const char *typeNameList, const char *typeList, const char *argList);
|
||||
|
||||
int main()
|
||||
{
|
||||
printf("#ifndef AS_GEN_WRAPPER_H\n"
|
||||
"#define AS_GEN_WRAPPER_H\n"
|
||||
"\n"
|
||||
"#ifndef ANGELSCRIPT_H\n"
|
||||
"// Avoid having to inform include path if header is already include before\n"
|
||||
"#include <angelscript.h>\n"
|
||||
"#endif\n"
|
||||
"#include <new>\n"
|
||||
"\n"
|
||||
"namespace gw {\n"
|
||||
"\n"
|
||||
"template <typename T> class Proxy {\n"
|
||||
" public:\n"
|
||||
" T value;\n"
|
||||
" Proxy(T value) : value(value) {}\n"
|
||||
" static T cast(void * ptr) {\n"
|
||||
" return reinterpret_cast<Proxy<T> *>(&ptr)->value;\n"
|
||||
" }\n"
|
||||
" private:\n"
|
||||
" Proxy(const Proxy &);\n"
|
||||
" Proxy & operator=(const Proxy &);\n"
|
||||
"};\n"
|
||||
"\n"
|
||||
"template <typename T> struct Wrapper {};\n"
|
||||
"template <typename T> struct ObjFirst {};\n"
|
||||
"template <typename T> struct ObjLast {};\n"
|
||||
"template <typename T> struct Constructor {};\n"
|
||||
"\n"
|
||||
"template <typename T>\n"
|
||||
"void destroy(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {\n"
|
||||
" static_cast<T *>(gen->GetObject())->~T();\n"
|
||||
"}\n");
|
||||
|
||||
string typename_list = "typename A0";
|
||||
string type_list = "A0";
|
||||
string arg_list = "\n static_cast<Proxy <A0> *>(gen->GetAddressOfArg(0))->value";
|
||||
string new_exp = "new (gen->GetAddressOfReturnLocation()) Proxy<R>";
|
||||
string obj_exp = "static_cast<T *>(gen->GetObject())->*";
|
||||
string obj_arg_exp = "\n Proxy<T>::cast(gen->GetObject())";
|
||||
|
||||
PrintTemplate("", "", "void", "", "", "", "", "void", "", "Wrapper");
|
||||
PrintTemplate("typename R", "", "R", "", "", new_exp.c_str(), "", "void", "", "Wrapper");
|
||||
PrintTemplate("typename T", "", "void", "T::", "", "", obj_exp.c_str(), "void", "", "Wrapper");
|
||||
PrintTemplate("typename T, typename R", "", "R", "T::", "", new_exp.c_str(), obj_exp.c_str(), "void", "", "Wrapper");
|
||||
PrintTemplate("typename T", "", "void", "T::", " const", "", obj_exp.c_str(), "void", "", "Wrapper");
|
||||
PrintTemplate("typename T, typename R", "", "R", "T::", " const", new_exp.c_str(), obj_exp.c_str(), "void", "", "Wrapper");
|
||||
|
||||
PrintTemplate("typename T", "", "void", "", "", "", "", "T", obj_arg_exp.c_str(), "ObjFirst");
|
||||
PrintTemplate("typename T, typename R", "", "R", "", "", new_exp.c_str(), "", "T", obj_arg_exp.c_str(), "ObjFirst");
|
||||
PrintTemplate("typename T", "", "void", "", "", "", "", "T", obj_arg_exp.c_str(), "ObjLast");
|
||||
PrintTemplate("typename T, typename R", "", "R", "", "", new_exp.c_str(), "", "T", obj_arg_exp.c_str(), "ObjLast");
|
||||
|
||||
PrintConstructor("", "", "", "");
|
||||
|
||||
for( int i = 0; i < max_args; i++ )
|
||||
{
|
||||
PrintTemplate("", typename_list.c_str(), "void", "", "", "", "", type_list.c_str(), arg_list.c_str(), "Wrapper");
|
||||
PrintTemplate("typename R, ", typename_list.c_str(), "R", "", "", new_exp.c_str(), "", type_list.c_str(), arg_list.c_str(), "Wrapper");
|
||||
PrintTemplate("typename T, ", typename_list.c_str(), "void", "T::", "", "", obj_exp.c_str(), type_list.c_str(), arg_list.c_str(), "Wrapper");
|
||||
PrintTemplate("typename T, typename R, ", typename_list.c_str(), "R", "T::", "", new_exp.c_str(), obj_exp.c_str(), type_list.c_str(), arg_list.c_str(), "Wrapper");
|
||||
PrintTemplate("typename T, ", typename_list.c_str(), "void", "T::", " const", "", obj_exp.c_str(), type_list.c_str(), arg_list.c_str(), "Wrapper");
|
||||
PrintTemplate("typename T, typename R, ", typename_list.c_str(), "R", "T::", " const", new_exp.c_str(), obj_exp.c_str(), type_list.c_str(), arg_list.c_str(), "Wrapper");
|
||||
|
||||
PrintTemplate("typename T, ", typename_list.c_str(), "void", "", "", "", "", ("T, " + type_list).c_str(), (obj_arg_exp + "," + arg_list).c_str(), "ObjFirst");
|
||||
PrintTemplate("typename T, typename R, ", typename_list.c_str(), "R", "", "", new_exp.c_str(), "", ("T, " + type_list).c_str(), (obj_arg_exp + "," + arg_list).c_str(), "ObjFirst");
|
||||
PrintTemplate("typename T, ", typename_list.c_str(), "void", "", "", "", "", (type_list + ", T").c_str(), (arg_list + "," + obj_arg_exp).c_str(), "ObjLast");
|
||||
PrintTemplate("typename T, typename R, ", typename_list.c_str(), "R", "", "", new_exp.c_str(), "", (type_list + ", T").c_str(), (arg_list + "," + obj_arg_exp).c_str(), "ObjLast");
|
||||
|
||||
PrintConstructor(", ", typename_list.c_str(), type_list.c_str(), arg_list.c_str());
|
||||
|
||||
char buf[5];
|
||||
sprintf(buf, "%d", i + 1);
|
||||
typename_list += ", typename A" + string(buf);
|
||||
type_list += ", A" + string(buf);
|
||||
arg_list += ",\n static_cast<Proxy <A" + string(buf) + "> *>(gen->GetAddressOfArg(" + string(buf) + "))->value";
|
||||
}
|
||||
|
||||
printf("template <typename T>\n"
|
||||
"struct Id {\n"
|
||||
" template <T fn_ptr> AS_NAMESPACE_QUALIFIER asSFuncPtr f(void) { return asFUNCTION(&Wrapper<T>::template f<fn_ptr>); }\n"
|
||||
" template <T fn_ptr> AS_NAMESPACE_QUALIFIER asSFuncPtr of(void) { return asFUNCTION(&ObjFirst<T>::template f<fn_ptr>); }\n"
|
||||
" template <T fn_ptr> AS_NAMESPACE_QUALIFIER asSFuncPtr ol(void) { return asFUNCTION(&ObjLast<T>::template f<fn_ptr>); }\n"
|
||||
"};\n"
|
||||
"\n"
|
||||
"template <typename T>\n"
|
||||
"Id<T> id(T fn_ptr) { return Id<T>(); }\n"
|
||||
"\n"
|
||||
"// On some versions of GNUC it is necessary to use the template keyword as disambiguator,\n"
|
||||
"// on others the template keyword gives an error, hence the need for the following define.\n"
|
||||
"// MSVC on the other hand seems to accept both with or without the template keyword.\n"
|
||||
"#if defined(__GNUC__) && (__GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 4))\n"
|
||||
" // GNUC 4.4.3 doesn't need the template keyword, and\n"
|
||||
" // hopefully upcoming versions won't need it either\n"
|
||||
" #define TMPL template\n"
|
||||
"#else\n"
|
||||
" #define TMPL\n"
|
||||
"#endif\n"
|
||||
"\n"
|
||||
"#define WRAP_FN(name) (::gw::id(name).TMPL f< name >())\n"
|
||||
"#define WRAP_MFN(ClassType, name) (::gw::id(&ClassType::name).TMPL f< &ClassType::name >())\n"
|
||||
"#define WRAP_OBJ_FIRST(name) (::gw::id(name).TMPL of< name >())\n"
|
||||
"#define WRAP_OBJ_LAST(name) (::gw::id(name).TMPL ol< name >())\n"
|
||||
"\n"
|
||||
"#define WRAP_FN_PR(name, Parameters, ReturnType) asFUNCTION((::gw::Wrapper<ReturnType (*)Parameters>::TMPL f< name >))\n"
|
||||
"#define WRAP_MFN_PR(ClassType, name, Parameters, ReturnType) asFUNCTION((::gw::Wrapper<ReturnType (ClassType::*)Parameters>::TMPL f< &ClassType::name >))\n"
|
||||
"#define WRAP_OBJ_FIRST_PR(name, Parameters, ReturnType) asFUNCTION((::gw::ObjFirst<ReturnType (*)Parameters>::TMPL f< name >))\n"
|
||||
"#define WRAP_OBJ_LAST_PR(name, Parameters, ReturnType) asFUNCTION((::gw::ObjLast<ReturnType (*)Parameters>::TMPL f< name >))\n"
|
||||
"\n"
|
||||
"#define WRAP_CON(ClassType, Parameters) asFUNCTION((::gw::Constructor<ClassType Parameters>::f))\n"
|
||||
"#define WRAP_DES(ClassType) asFUNCTION((::gw::destroy<ClassType>))\n"
|
||||
"\n"
|
||||
"} // end namespace gw\n"
|
||||
"\n"
|
||||
"#endif\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void PrintTemplate(const char *base, const char *typeNameList, const char *retType, const char *objType, const char *isConst, const char *newExpr, const char *objExpr, const char *argList1, const char *argList2, const char *wrapName)
|
||||
{
|
||||
printf("template <%s%s>\n", base, typeNameList);
|
||||
printf("struct %s<%s (%s*)(%s)%s> {\n", wrapName, retType, objType, argList1, isConst);
|
||||
printf(" template <%s (%s*fp)(%s)%s>\n", retType, objType, argList1, isConst);
|
||||
printf(" static void f(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {\n");
|
||||
printf(" %s((%sfp)(%s));\n", newExpr, objExpr, argList2);
|
||||
printf(" }\n");
|
||||
printf("};\n");
|
||||
}
|
||||
|
||||
void PrintConstructor(const char *comma, const char *typeNameList, const char *typeList, const char *argList)
|
||||
{
|
||||
printf("template <typename T%s%s>\n", comma, typeNameList);
|
||||
printf("struct Constructor <T (%s)> {\n", typeList);
|
||||
printf(" static void f(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {\n");
|
||||
printf(" new (gen->GetObject()) T(%s);\n", argList);
|
||||
printf(" }\n");
|
||||
printf("};\n");
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
|
||||
Microsoft Visual Studio Solution File, Format Version 10.00
|
||||
# Visual C++ Express 2008
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "generator", "generator.vcproj", "{086A2F1A-01B1-4EB3-A8FA-0926FF10E953}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Win32 = Debug|Win32
|
||||
Release|Win32 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{086A2F1A-01B1-4EB3-A8FA-0926FF10E953}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{086A2F1A-01B1-4EB3-A8FA-0926FF10E953}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{086A2F1A-01B1-4EB3-A8FA-0926FF10E953}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{086A2F1A-01B1-4EB3-A8FA-0926FF10E953}.Release|Win32.Build.0 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
EndGlobal
|
|
@ -0,0 +1,236 @@
|
|||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="9,00"
|
||||
Name="generator"
|
||||
ProjectGUID="{086A2F1A-01B1-4EB3-A8FA-0926FF10E953}"
|
||||
TargetFrameworkVersion="0"
|
||||
>
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"
|
||||
/>
|
||||
</Platforms>
|
||||
<ToolFiles>
|
||||
</ToolFiles>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
OutputDirectory=".\Debug"
|
||||
IntermediateDirectory=".\Debug"
|
||||
ConfigurationType="1"
|
||||
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
|
||||
UseOfMFC="0"
|
||||
ATLMinimizesCRunTimeLibraryUsage="false"
|
||||
CharacterSet="2"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
TypeLibraryName=".\Debug/generator.tlb"
|
||||
HeaderFileName=""
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
|
||||
MinimalRebuild="true"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="1"
|
||||
PrecompiledHeaderFile=".\Debug/generator.pch"
|
||||
AssemblerListingLocation=".\Debug/"
|
||||
ObjectFile=".\Debug/"
|
||||
ProgramDataBaseFileName=".\Debug/"
|
||||
WarningLevel="3"
|
||||
SuppressStartupBanner="true"
|
||||
DebugInformationFormat="4"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
PreprocessorDefinitions="_DEBUG"
|
||||
Culture="1033"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
OutputFile=".\Debug/generator.exe"
|
||||
LinkIncremental="2"
|
||||
SuppressStartupBanner="true"
|
||||
GenerateDebugInformation="true"
|
||||
ProgramDatabaseFile=".\Debug/generator.pdb"
|
||||
SubSystem="1"
|
||||
RandomizedBaseAddress="1"
|
||||
DataExecutionPrevention="0"
|
||||
TargetMachine="1"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
SuppressStartupBanner="true"
|
||||
OutputFile=".\Debug/generator.bsc"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
OutputDirectory=".\Release"
|
||||
IntermediateDirectory=".\Release"
|
||||
ConfigurationType="1"
|
||||
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
|
||||
UseOfMFC="0"
|
||||
ATLMinimizesCRunTimeLibraryUsage="false"
|
||||
CharacterSet="2"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
TypeLibraryName=".\Release/generator.tlb"
|
||||
HeaderFileName=""
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="2"
|
||||
InlineFunctionExpansion="1"
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
|
||||
StringPooling="true"
|
||||
RuntimeLibrary="0"
|
||||
EnableFunctionLevelLinking="true"
|
||||
PrecompiledHeaderFile=".\Release/generator.pch"
|
||||
AssemblerListingLocation=".\Release/"
|
||||
ObjectFile=".\Release/"
|
||||
ProgramDataBaseFileName=".\Release/"
|
||||
WarningLevel="3"
|
||||
SuppressStartupBanner="true"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
PreprocessorDefinitions="NDEBUG"
|
||||
Culture="1033"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
OutputFile=".\Release/generator.exe"
|
||||
LinkIncremental="1"
|
||||
SuppressStartupBanner="true"
|
||||
ProgramDatabaseFile=".\Release/generator.pdb"
|
||||
SubSystem="1"
|
||||
RandomizedBaseAddress="1"
|
||||
DataExecutionPrevention="0"
|
||||
TargetMachine="1"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
SuppressStartupBanner="true"
|
||||
OutputFile=".\Release/generator.bsc"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<Filter
|
||||
Name="Source Files"
|
||||
Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
|
||||
>
|
||||
<File
|
||||
RelativePath="generateheader.cpp"
|
||||
>
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
PreprocessorDefinitions=""
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
PreprocessorDefinitions=""
|
||||
/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Header Files"
|
||||
Filter="h;hpp;hxx;hm;inl"
|
||||
>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Resource Files"
|
||||
Filter="ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
|
||||
>
|
||||
</Filter>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
|
@ -0,0 +1,401 @@
|
|||
#include <assert.h>
|
||||
#include <string>
|
||||
|
||||
#include "contextmgr.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
// TODO: Should have a pool of free asIScriptContext so that new contexts
|
||||
// won't be allocated every time. The application must not keep
|
||||
// its own references, instead it must tell the context manager
|
||||
// that it is using the context. Otherwise the context manager may
|
||||
// think it can reuse the context too early.
|
||||
|
||||
// TODO: Need to have a callback for when scripts finishes, so that the
|
||||
// application can receive return values.
|
||||
|
||||
BEGIN_AS_NAMESPACE
|
||||
|
||||
// The id for the context manager user data.
|
||||
// The add-ons have reserved the numbers 1000
|
||||
// through 1999 for this purpose, so we should be fine.
|
||||
const asPWORD CONTEXT_MGR = 1002;
|
||||
|
||||
struct SContextInfo
|
||||
{
|
||||
asUINT sleepUntil;
|
||||
vector<asIScriptContext*> coRoutines;
|
||||
asUINT currentCoRoutine;
|
||||
asIScriptContext * keepCtxAfterExecution;
|
||||
};
|
||||
|
||||
static void ScriptSleep(asUINT milliSeconds)
|
||||
{
|
||||
// Get a pointer to the context that is currently being executed
|
||||
asIScriptContext *ctx = asGetActiveContext();
|
||||
if( ctx )
|
||||
{
|
||||
// Get the context manager from the user data
|
||||
CContextMgr *ctxMgr = reinterpret_cast<CContextMgr*>(ctx->GetUserData(CONTEXT_MGR));
|
||||
if( ctxMgr )
|
||||
{
|
||||
// Suspend its execution. The VM will continue until the current
|
||||
// statement is finished and then return from the Execute() method
|
||||
ctx->Suspend();
|
||||
|
||||
// Tell the context manager when the context is to continue execution
|
||||
ctxMgr->SetSleeping(ctx, milliSeconds);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void ScriptYield()
|
||||
{
|
||||
// Get a pointer to the context that is currently being executed
|
||||
asIScriptContext *ctx = asGetActiveContext();
|
||||
if( ctx )
|
||||
{
|
||||
// Get the context manager from the user data
|
||||
CContextMgr *ctxMgr = reinterpret_cast<CContextMgr*>(ctx->GetUserData(CONTEXT_MGR));
|
||||
if( ctxMgr )
|
||||
{
|
||||
// Let the context manager know that it should run the next co-routine
|
||||
ctxMgr->NextCoRoutine();
|
||||
|
||||
// The current context must be suspended so that VM will return from
|
||||
// the Execute() method where the context manager will continue.
|
||||
ctx->Suspend();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ScriptCreateCoRoutine(asIScriptFunction *func, CScriptDictionary *arg)
|
||||
{
|
||||
if( func == 0 )
|
||||
return;
|
||||
|
||||
asIScriptContext *ctx = asGetActiveContext();
|
||||
if( ctx )
|
||||
{
|
||||
// Get the context manager from the user data
|
||||
CContextMgr *ctxMgr = reinterpret_cast<CContextMgr*>(ctx->GetUserData(CONTEXT_MGR));
|
||||
if( ctxMgr )
|
||||
{
|
||||
// Create a new context for the co-routine
|
||||
asIScriptContext *coctx = ctxMgr->AddContextForCoRoutine(ctx, func);
|
||||
|
||||
// Pass the argument to the context
|
||||
coctx->SetArgObject(0, arg);
|
||||
|
||||
// The context manager will call Execute() on the context when it is time
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef AS_MAX_PORTABILITY
|
||||
void ScriptYield_generic(asIScriptGeneric *)
|
||||
{
|
||||
ScriptYield();
|
||||
}
|
||||
|
||||
void ScriptCreateCoRoutine_generic(asIScriptGeneric *gen)
|
||||
{
|
||||
asIScriptFunction *func = reinterpret_cast<asIScriptFunction*>(gen->GetArgAddress(0));
|
||||
CScriptDictionary *dict = reinterpret_cast<CScriptDictionary*>(gen->GetArgAddress(1));
|
||||
ScriptCreateCoRoutine(func, dict);
|
||||
}
|
||||
#endif
|
||||
|
||||
CContextMgr::CContextMgr()
|
||||
{
|
||||
m_getTimeFunc = 0;
|
||||
m_currentThread = 0;
|
||||
|
||||
m_numExecutions = 0;
|
||||
m_numGCObjectsCreated = 0;
|
||||
m_numGCObjectsDestroyed = 0;
|
||||
}
|
||||
|
||||
CContextMgr::~CContextMgr()
|
||||
{
|
||||
asUINT n;
|
||||
|
||||
// Free the memory
|
||||
for( n = 0; n < m_threads.size(); n++ )
|
||||
{
|
||||
if( m_threads[n] )
|
||||
{
|
||||
for( asUINT c = 0; c < m_threads[n]->coRoutines.size(); c++ )
|
||||
{
|
||||
asIScriptContext *ctx = m_threads[n]->coRoutines[c];
|
||||
if( ctx )
|
||||
{
|
||||
// Return the context to the engine (and possible context pool configured in it)
|
||||
ctx->GetEngine()->ReturnContext(ctx);
|
||||
}
|
||||
}
|
||||
|
||||
delete m_threads[n];
|
||||
}
|
||||
}
|
||||
|
||||
for( n = 0; n < m_freeThreads.size(); n++ )
|
||||
{
|
||||
if( m_freeThreads[n] )
|
||||
{
|
||||
assert( m_freeThreads[n]->coRoutines.size() == 0 );
|
||||
|
||||
delete m_freeThreads[n];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int CContextMgr::ExecuteScripts()
|
||||
{
|
||||
// TODO: Should have an optional time out for this function. If not all scripts executed before the
|
||||
// time out, the next time the function is called the loop should continue
|
||||
// where it left off.
|
||||
|
||||
// TODO: There should be a time out per thread as well. If a thread executes for too
|
||||
// long, it should be aborted. A group of co-routines count as a single thread.
|
||||
|
||||
// Check if the system time is higher than the time set for the contexts
|
||||
asUINT time = m_getTimeFunc ? m_getTimeFunc() : asUINT(-1);
|
||||
for( m_currentThread = 0; m_currentThread < m_threads.size(); m_currentThread++ )
|
||||
{
|
||||
SContextInfo *thread = m_threads[m_currentThread];
|
||||
if( thread->sleepUntil < time )
|
||||
{
|
||||
int currentCoRoutine = thread->currentCoRoutine;
|
||||
|
||||
// Gather some statistics from the GC
|
||||
asIScriptEngine *engine = thread->coRoutines[currentCoRoutine]->GetEngine();
|
||||
asUINT gcSize1, gcSize2, gcSize3;
|
||||
engine->GetGCStatistics(&gcSize1);
|
||||
|
||||
// Execute the script for this thread and co-routine
|
||||
int r = thread->coRoutines[currentCoRoutine]->Execute();
|
||||
|
||||
// Determine how many new objects were created in the GC
|
||||
engine->GetGCStatistics(&gcSize2);
|
||||
m_numGCObjectsCreated += gcSize2 - gcSize1;
|
||||
m_numExecutions++;
|
||||
|
||||
if( r != asEXECUTION_SUSPENDED )
|
||||
{
|
||||
// The context has terminated execution (for one reason or other)
|
||||
// Unless the application has requested to keep the context we'll return it to the pool now
|
||||
if( thread->keepCtxAfterExecution != thread->coRoutines[currentCoRoutine] )
|
||||
engine->ReturnContext(thread->coRoutines[currentCoRoutine]);
|
||||
thread->coRoutines[currentCoRoutine] = 0;
|
||||
|
||||
thread->coRoutines.erase(thread->coRoutines.begin() + thread->currentCoRoutine);
|
||||
if( thread->currentCoRoutine >= thread->coRoutines.size() )
|
||||
thread->currentCoRoutine = 0;
|
||||
|
||||
// If this was the last co-routine terminate the thread
|
||||
if( thread->coRoutines.size() == 0 )
|
||||
{
|
||||
m_freeThreads.push_back(thread);
|
||||
m_threads.erase(m_threads.begin() + m_currentThread);
|
||||
m_currentThread--;
|
||||
}
|
||||
}
|
||||
|
||||
// Destroy all known garbage if any new objects were created
|
||||
if( gcSize2 > gcSize1 )
|
||||
{
|
||||
engine->GarbageCollect(asGC_FULL_CYCLE | asGC_DESTROY_GARBAGE);
|
||||
|
||||
// Determine how many objects were destroyed
|
||||
engine->GetGCStatistics(&gcSize3);
|
||||
m_numGCObjectsDestroyed += gcSize3 - gcSize2;
|
||||
}
|
||||
|
||||
// TODO: If more objects are created per execution than destroyed on average
|
||||
// then it may be necessary to run more iterations of the detection of
|
||||
// cyclic references. At the startup of an application there is usually
|
||||
// a lot of objects created that will live on through out the application
|
||||
// so the average number of objects created per execution will be higher
|
||||
// than the number of destroyed objects in the beginning, but afterwards
|
||||
// it usually levels out to be more or less equal.
|
||||
|
||||
// Just run an incremental step for detecting cyclic references
|
||||
engine->GarbageCollect(asGC_ONE_STEP | asGC_DETECT_GARBAGE);
|
||||
}
|
||||
}
|
||||
|
||||
return int(m_threads.size());
|
||||
}
|
||||
|
||||
void CContextMgr::DoneWithContext(asIScriptContext *ctx)
|
||||
{
|
||||
ctx->GetEngine()->ReturnContext(ctx);
|
||||
}
|
||||
|
||||
void CContextMgr::NextCoRoutine()
|
||||
{
|
||||
m_threads[m_currentThread]->currentCoRoutine++;
|
||||
if( m_threads[m_currentThread]->currentCoRoutine >= m_threads[m_currentThread]->coRoutines.size() )
|
||||
m_threads[m_currentThread]->currentCoRoutine = 0;
|
||||
}
|
||||
|
||||
void CContextMgr::AbortAll()
|
||||
{
|
||||
// Abort all contexts and release them. The script engine will make
|
||||
// sure that all resources held by the scripts are properly released.
|
||||
|
||||
for( asUINT n = 0; n < m_threads.size(); n++ )
|
||||
{
|
||||
for( asUINT c = 0; c < m_threads[n]->coRoutines.size(); c++ )
|
||||
{
|
||||
asIScriptContext *ctx = m_threads[n]->coRoutines[c];
|
||||
if( ctx )
|
||||
{
|
||||
ctx->Abort();
|
||||
ctx->GetEngine()->ReturnContext(ctx);
|
||||
ctx = 0;
|
||||
}
|
||||
}
|
||||
m_threads[n]->coRoutines.resize(0);
|
||||
|
||||
m_freeThreads.push_back(m_threads[n]);
|
||||
}
|
||||
|
||||
m_threads.resize(0);
|
||||
|
||||
m_currentThread = 0;
|
||||
}
|
||||
|
||||
asIScriptContext *CContextMgr::AddContext(asIScriptEngine *engine, asIScriptFunction *func, bool keepCtxAfterExec)
|
||||
{
|
||||
// Use RequestContext instead of CreateContext so we can take
|
||||
// advantage of possible context pooling configured with the engine
|
||||
asIScriptContext *ctx = engine->RequestContext();
|
||||
if( ctx == 0 )
|
||||
return 0;
|
||||
|
||||
// Prepare it to execute the function
|
||||
int r = ctx->Prepare(func);
|
||||
if( r < 0 )
|
||||
{
|
||||
engine->ReturnContext(ctx);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Set the context manager as user data with the context so it
|
||||
// can be retrieved by the functions registered with the engine
|
||||
ctx->SetUserData(this, CONTEXT_MGR);
|
||||
|
||||
// Add the context to the list for execution
|
||||
SContextInfo *info = 0;
|
||||
if( m_freeThreads.size() > 0 )
|
||||
{
|
||||
info = *m_freeThreads.rbegin();
|
||||
m_freeThreads.pop_back();
|
||||
}
|
||||
else
|
||||
{
|
||||
info = new SContextInfo;
|
||||
}
|
||||
|
||||
info->coRoutines.push_back(ctx);
|
||||
info->currentCoRoutine = 0;
|
||||
info->sleepUntil = 0;
|
||||
info->keepCtxAfterExecution = keepCtxAfterExec ? ctx : 0;
|
||||
m_threads.push_back(info);
|
||||
|
||||
return ctx;
|
||||
}
|
||||
|
||||
asIScriptContext *CContextMgr::AddContextForCoRoutine(asIScriptContext *currCtx, asIScriptFunction *func)
|
||||
{
|
||||
asIScriptEngine *engine = currCtx->GetEngine();
|
||||
asIScriptContext *coctx = engine->RequestContext();
|
||||
if( coctx == 0 )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Prepare the context
|
||||
int r = coctx->Prepare(func);
|
||||
if( r < 0 )
|
||||
{
|
||||
// Couldn't prepare the context
|
||||
engine->ReturnContext(coctx);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Set the context manager as user data with the context so it
|
||||
// can be retrieved by the functions registered with the engine
|
||||
coctx->SetUserData(this, CONTEXT_MGR);
|
||||
|
||||
// Find the current context thread info
|
||||
// TODO: Start with the current thread so that we can find the group faster
|
||||
for( asUINT n = 0; n < m_threads.size(); n++ )
|
||||
{
|
||||
if( m_threads[n]->coRoutines[m_threads[n]->currentCoRoutine] == currCtx )
|
||||
{
|
||||
// Add the coRoutine to the list
|
||||
m_threads[n]->coRoutines.push_back(coctx);
|
||||
}
|
||||
}
|
||||
|
||||
return coctx;
|
||||
}
|
||||
|
||||
void CContextMgr::SetSleeping(asIScriptContext *ctx, asUINT milliSeconds)
|
||||
{
|
||||
assert( m_getTimeFunc != 0 );
|
||||
|
||||
// Find the context and update the timeStamp
|
||||
// for when the context is to be continued
|
||||
|
||||
// TODO: Start with the current thread
|
||||
|
||||
for( asUINT n = 0; n < m_threads.size(); n++ )
|
||||
{
|
||||
if( m_threads[n]-> |