Daniele Bartolini 10 лет назад
Родитель
Сommit
2d27df7ff6
4 измененных файлов с 92 добавлено и 40 удалено
  1. 13 16
      src/lua/lua_environment.cpp
  2. 3 3
      src/lua/lua_environment.h
  3. 47 21
      src/lua/lua_stack.cpp
  4. 29 0
      src/lua/lua_stack.h

+ 13 - 16
src/lua/lua_environment.cpp

@@ -295,6 +295,12 @@ Vector3* LuaEnvironment::next_vector3(const Vector3& v)
 	return &(_vec3_buffer[_vec3_used++] = v);
 }
 
+Quaternion* LuaEnvironment::next_quaternion(const Quaternion& q)
+{
+	CE_ASSERT(_quat_used < CROWN_MAX_LUA_QUATERNION, "Maximum number of Quaternion reached");
+	return &(_quat_buffer[_quat_used++] = q);
+}
+
 Matrix4x4* LuaEnvironment::next_matrix4x4(const Matrix4x4& m)
 {
 	CE_ASSERT(_mat4_used < CROWN_MAX_LUA_MATRIX4X4, "Maximum number of Matrix4x4 reached");
@@ -302,35 +308,26 @@ Matrix4x4* LuaEnvironment::next_matrix4x4(const Matrix4x4& m)
 	return &(s_mat4_buffer[_mat4_used++] = m);
 }
 
-Quaternion* LuaEnvironment::next_quaternion(const Quaternion& q)
-{
-	CE_ASSERT(_quat_used < CROWN_MAX_LUA_QUATERNION, "Maximum number of Quaternion reached");
-	return &(_quat_buffer[_quat_used++] = q);
-}
-
-bool LuaEnvironment::is_vector3(int index)
+bool LuaEnvironment::is_vector3(const Vector3* p)
 {
-	void* type = lua_touserdata(L, index);
-	return (type >= &_vec3_buffer[0] && type <= &_vec3_buffer[CROWN_MAX_LUA_VECTOR3 - 1]);
+	return (p >= &_vec3_buffer[0] && p <= &_vec3_buffer[CROWN_MAX_LUA_VECTOR3 - 1]);
 }
 
-bool LuaEnvironment::is_matrix4x4(int index)
+bool LuaEnvironment::is_quaternion(const Quaternion* p)
 {
-	void* type = lua_touserdata(L, index);
-	return (type >= &s_mat4_buffer[0] && type <= &s_mat4_buffer[CROWN_MAX_LUA_MATRIX4X4 - 1]);
+	return (p >= &_quat_buffer[0] && p <= &_quat_buffer[CROWN_MAX_LUA_QUATERNION - 1]);
 }
 
-bool LuaEnvironment::is_quaternion(int index)
+bool LuaEnvironment::is_matrix4x4(const Matrix4x4* p)
 {
-	void* type = lua_touserdata(L, index);
-	return (type >= &_quat_buffer[0] && type <= &_quat_buffer[CROWN_MAX_LUA_QUATERNION - 1]);
+	return (p >= &s_mat4_buffer[0] && p <= &s_mat4_buffer[CROWN_MAX_LUA_MATRIX4X4 - 1]);
 }
 
 void LuaEnvironment::clear_temporaries()
 {
 	_vec3_used = 0;
-	_mat4_used = 0;
 	_quat_used = 0;
+	_mat4_used = 0;
 }
 
 } // namespace crown

+ 3 - 3
src/lua/lua_environment.h

@@ -57,9 +57,9 @@ struct LuaEnvironment
 	Vector3* next_vector3(const Vector3& v);
 	Quaternion* next_quaternion(const Quaternion& q);
 	Matrix4x4* next_matrix4x4(const Matrix4x4& m);
-	bool is_vector3(int i);
-	bool is_quaternion(int i);
-	bool is_matrix4x4(int i);
+	bool is_vector3(const Vector3* p);
+	bool is_quaternion(const Quaternion* p);
+	bool is_matrix4x4(const Matrix4x4* p);
 
 	// FIXME
 	void call_physics_callback(Actor* actor_0, Actor* actor_1, Unit* unit_0, Unit* unit_1, const Vector3& where, const Vector3& normal, const char* type);

+ 47 - 21
src/lua/lua_stack.cpp

@@ -10,40 +10,72 @@
 namespace crown
 {
 
-bool is_vector3(int i) { return device()->lua_environment()->is_vector3(i); }
-bool is_quaternion(int i) { return device()->lua_environment()->is_quaternion(i); }
-bool is_matrix4x4(int i) { return device()->lua_environment()->is_matrix4x4(i); }
+bool LuaStack::is_vector3(int i)
+{
+	return device()->lua_environment()->is_vector3((Vector3*)get_pointer(i));
+}
+
+bool LuaStack::is_quaternion(int i)
+{
+	return device()->lua_environment()->is_quaternion((Quaternion*)get_pointer(i));
+}
+
+bool LuaStack::is_matrix4x4(int i)
+{
+	return device()->lua_environment()->is_matrix4x4((Matrix4x4*)get_pointer(i));
+}
+
+void LuaStack::check_temporary(int i, Vector3* p)
+{
+	LuaEnvironment* env = device()->lua_environment();
+	if (!is_pointer(i) || !env->is_vector3(p))
+		luaL_typerror(L, i, "Vector3");
+}
+
+void LuaStack::check_temporary(int i, Quaternion* p)
+{
+	LuaEnvironment* env = device()->lua_environment();
+	if (!is_pointer(i) || !env->is_quaternion(p))
+		luaL_typerror(L, i, "Quaternion");
+}
+
+void LuaStack::check_temporary(int i, Matrix4x4* p)
+{
+	LuaEnvironment* env = device()->lua_environment();
+	if (!is_pointer(i) || !env->is_matrix4x4(p))
+		luaL_typerror(L, i, "Matrix4x4");
+}
 
 Vector2 LuaStack::get_vector2(int i)
 {
-	void* v = CHECKLIGHTDATA(L, i, is_vector3, "Vector2");
-	Vector3& vv = *(Vector3*)v;
-	return vector2(vv.x, vv.y);
+	Vector3 v = get_vector3(i);
+	return vector2(v.x, v.y);
 }
 
 Vector3& LuaStack::get_vector3(int i)
 {
-	void* v = CHECKLIGHTDATA(L, i, is_vector3, "Vector3");
-	return *(Vector3*)v;
+	Vector3* v = (Vector3*)get_pointer(i);
+	check_temporary(i, v);
+	return *v;
 }
 
 Quaternion& LuaStack::get_quaternion(int i)
 {
-	void* q = CHECKLIGHTDATA(L, i, is_quaternion, "Quaternion");
-	return *(Quaternion*)q;
+	Quaternion* q = (Quaternion*)get_pointer(i);
+	check_temporary(i, q);
+	return *q;
 }
 
 Matrix4x4& LuaStack::get_matrix4x4(int i)
 {
-	void* m = CHECKLIGHTDATA(L, i, is_matrix4x4, "Matrix4x4");
-	return *(Matrix4x4*)m;
+	Matrix4x4* m = (Matrix4x4*)get_pointer(i);
+	check_temporary(i, m);
+	return *m;
 }
 
 Color4 LuaStack::get_color4(int i)
 {
-	// Color4 represented as Quaternion
-	void* c = CHECKLIGHTDATA(L, i, is_quaternion, "Color4");
-	Quaternion& q = *(Quaternion*)c;
+	Quaternion q = get_quaternion(i);
 	return color4(q.x, q.y, q.z, q.w);
 }
 
@@ -55,22 +87,16 @@ void LuaStack::push_vector2(const Vector2& v)
 void LuaStack::push_vector3(const Vector3& v)
 {
 	lua_pushlightuserdata(L, device()->lua_environment()->next_vector3(v));
-	luaL_getmetatable(L, "Lightuserdata_mt");
-	lua_setmetatable(L, -2);
 }
 
 void LuaStack::push_quaternion(const Quaternion& q)
 {
 	lua_pushlightuserdata(L, device()->lua_environment()->next_quaternion(q));
-	luaL_getmetatable(L, "Lightuserdata_mt");
-	lua_setmetatable(L, -2);
 }
 
 void LuaStack::push_matrix4x4(const Matrix4x4& m)
 {
 	lua_pushlightuserdata(L, device()->lua_environment()->next_matrix4x4(m));
-	luaL_getmetatable(L, "Lightuserdata_mt");
-	lua_setmetatable(L, -2);
 }
 
 } // namespace crown

+ 29 - 0
src/lua/lua_stack.h

@@ -112,16 +112,31 @@ struct LuaStack
 	{
 		lua_pop(L, n);
 	}
+
 	bool is_nil(int i)
 	{
 		return lua_isnil(L, i) == 1;
 	}
 
+	bool is_bool(int i)
+	{
+		return lua_isboolean(L, i) == 1;
+	}
+
 	bool is_number(int i)
 	{
 		return lua_isnumber(L, i) == 1;
 	}
 
+	bool is_pointer(int i)
+	{
+		return lua_islightuserdata(L, i) == 1 && ((uintptr_t)lua_touserdata(L, i) & 0x3) == 0;
+	}
+
+	bool is_vector3(int i);
+	bool is_quaternion(int i);
+	bool is_matrix4x4(int i);
+
 	/// Wraps lua_type.
 	int value_type(int i)
 	{
@@ -176,6 +191,11 @@ struct LuaStack
 		lua_pushlstring(L, s, len);
 	}
 
+	void push_pointer(void* p)
+	{
+		lua_pushlightuserdata(L, p);
+	}
+
 	bool get_bool(int i)
 	{
 		return CHECKBOOLEAN(L, i) == 1;
@@ -206,6 +226,11 @@ struct LuaStack
 		return CHECKSTRING(L, i);
 	}
 
+	void* get_pointer(int i)
+	{
+		return lua_touserdata(L, i);
+	}
+
 	/// Pushes an empty table onto the stack.
 	/// When you want to set keys on the table, you have to use LuaStack::push_key_begin()
 	/// and LuaStack::push_key_end() as in the following example:
@@ -487,6 +512,10 @@ struct LuaStack
 		return *m;
 	}
 
+	void check_temporary(int i, Vector3* p);
+	void check_temporary(int i, Quaternion* p);
+	void check_temporary(int i, Matrix4x4* p);
+
 private:
 
 	lua_State* L;