#ifndef WIN32 #define WEAK __attribute__ ((weak)) #else #define WEAK #endif #include class SimpleRandom : public Base { public: SimpleRandom(Uint32 seedValue = 0) { if (seedValue == 0) { seedValue = time(NULL); } state = (seedValue | (seedValue << 32) | 1) * prime; } Uint8 GetNext() { state *= prime; return (Uint8) (state >> 21); } Uint32 GetNext32() { Uint32 ret = 0; ret <<= 8; ret | GetNext(); ret <<= 8; ret | GetNext(); ret <<= 8; ret | GetNext(); ret <<= 8; ret | GetNext(); return ret; } float GetFloat() { return (float)GetNext32() / 4294967296.0f; } private: Uint64 state; const static Uint64 prime = 4294967357ULL; }; class LuaSimpleRandom : public LuaObject { public: static void pushstatics(Lua *) throw (GeneralException); LuaSimpleRandom(SimpleRandom * _sr) : sr(_sr) { } protected: virtual void pushmembers(Lua *); SimpleRandom * sr; }; enum SimpleRandom_functions_t { SIMPLERANDOM_NEWSIMPLERANDOM, }; enum SimpleRandom_methods_t { SIMPLERANDOM_GETNEXT, SIMPLERANDOM_GETNEXT32, SIMPLERANDOM_GETFLOAT, }; struct lua_functypes_t SimpleRandom_functions[] = { { SIMPLERANDOM_NEWSIMPLERANDOM, "SimpleRandom", 0, 1, { BLUA_NUMBER } }, { -1, 0, 0, 0, 0 }, }; struct lua_functypes_t SimpleRandom_methods[] = { { SIMPLERANDOM_GETNEXT, "GetNext", 0, 0, { } }, { SIMPLERANDOM_GETNEXT32, "GetNext32", 0, 0, { } }, { SIMPLERANDOM_GETFLOAT, "GetFloat", 0, 0, { } }, { -1, 0, 0, 0, 0 }, }; class sLua_SimpleRandom : public Base { public: DECLARE_FUNCTION(SimpleRandom, SIMPLERANDOM_NEWSIMPLERANDOM); DECLARE_METHOD(SimpleRandom, SIMPLERANDOM_GETNEXT); DECLARE_METHOD(SimpleRandom, SIMPLERANDOM_GETNEXT32); DECLARE_METHOD(SimpleRandom, SIMPLERANDOM_GETFLOAT); private: static int SimpleRandom_proceed(Lua * L, int n, SimpleRandom * obj, int caller); static int SimpleRandom_proceed_statics(Lua * L, int n, int caller); }; void LuaSimpleRandom::pushmembers(Lua * L) { pushme(L, sr, "SimpleRandom"); PUSH_METHOD(SimpleRandom, SIMPLERANDOM_GETNEXT); PUSH_METHOD(SimpleRandom, SIMPLERANDOM_GETNEXT32); PUSH_METHOD(SimpleRandom, SIMPLERANDOM_GETFLOAT); } void LuaSimpleRandom::pushstatics(Lua * L) throw (GeneralException) { CHECK_METHODS(SimpleRandom); CHECK_FUNCTIONS(SimpleRandom); PUSH_FUNCTION(SimpleRandom, SIMPLERANDOM_NEWSIMPLERANDOM); } int sLua_SimpleRandom::SimpleRandom_proceed_statics(Lua * L, int n, int caller) { int r = 1; switch (caller) { case SIMPLERANDOM_NEWSIMPLERANDOM: { LuaSimpleRandom sr(new SimpleRandom(n == 1 ? L->tonumber() : 0)); sr.pushdestruct(L); } break; } return r; } int sLua_SimpleRandom::SimpleRandom_proceed(Lua * L, int n, SimpleRandom * sr, int caller) { int r = 1; switch(caller) { case SIMPLERANDOM_GETNEXT: L->push((lua_Number) sr->GetNext()); break; case SIMPLERANDOM_GETNEXT32: L->push((lua_Number) sr->GetNext32()); break; case SIMPLERANDOM_GETFLOAT: L->push((lua_Number) sr->GetFloat()); break; } return r; } static void _init_plugin(Lua * L) { static bool done = false; if (done) return; done = true; LuaSimpleRandom::pushstatics(L); } extern "C" { WEAK void init_plugin(Lua * L) { _init_plugin(L); } void luarand_init(Lua * L) { _init_plugin(L); } }