summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/plugin-luarand.cc146
1 files changed, 146 insertions, 0 deletions
diff --git a/src/plugin-luarand.cc b/src/plugin-luarand.cc
new file mode 100644
index 0000000..ea0ad30
--- /dev/null
+++ b/src/plugin-luarand.cc
@@ -0,0 +1,146 @@
+#ifndef WIN32
+#define WEAK __attribute__ ((weak))
+#else
+#define WEAK
+#endif
+
+#include <BLua.h>
+
+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);
+}
+
+}
+