2
0
Эх сурвалжийг харах

Merge dynamiccore2 into minor

Instead of a global type enum and bitfield, all types now have their own
love::Type static member. This means they automatically assign their ids, build
their bitsets, etc. As a bonus, it simplifies wrapper code since most functions
already know which type they're pushing to or getting from lua, so they can
directly get the static member (if it's called 'type').

--HG--
branch : minor
Bart van Strien 8 жил өмнө
parent
commit
7bd3581a52
100 өөрчлөгдсөн 633 нэмэгдсэн , 493 устгасан
  1. 5 0
      CMakeLists.txt
  2. 29 0
      src/common/Data.cpp
  3. 2 0
      src/common/Data.h
  4. 1 0
      src/common/Module.cpp
  5. 2 0
      src/common/Module.h
  6. 2 0
      src/common/Object.cpp
  7. 3 0
      src/common/Object.h
  8. 29 0
      src/common/Stream.cpp
  9. 2 0
      src/common/Stream.h
  10. 8 8
      src/common/Variant.cpp
  11. 2 2
      src/common/Variant.h
  12. 28 33
      src/common/runtime.cpp
  13. 60 24
      src/common/runtime.h
  14. 41 106
      src/common/types.cpp
  15. 39 104
      src/common/types.h
  16. 2 2
      src/common/wrap_Data.cpp
  17. 2 0
      src/modules/audio/RecordingDevice.cpp
  18. 3 0
      src/modules/audio/RecordingDevice.h
  19. 5 3
      src/modules/audio/Source.cpp
  20. 3 1
      src/modules/audio/Source.h
  21. 21 21
      src/modules/audio/openal/Source.cpp
  22. 12 12
      src/modules/audio/wrap_Audio.cpp
  23. 4 4
      src/modules/audio/wrap_RecordingDevice.cpp
  24. 5 5
      src/modules/audio/wrap_Source.cpp
  25. 8 8
      src/modules/event/sdl/Event.cpp
  26. 1 1
      src/modules/event/wrap_Event.cpp
  27. 2 0
      src/modules/filesystem/DroppedFile.cpp
  28. 2 0
      src/modules/filesystem/DroppedFile.h
  29. 2 0
      src/modules/filesystem/File.cpp
  30. 2 0
      src/modules/filesystem/File.h
  31. 2 0
      src/modules/filesystem/FileData.cpp
  32. 2 0
      src/modules/filesystem/FileData.h
  33. 2 0
      src/modules/filesystem/Filesystem.cpp
  34. 2 0
      src/modules/filesystem/Filesystem.h
  35. 2 2
      src/modules/filesystem/wrap_DroppedFile.cpp
  36. 5 5
      src/modules/filesystem/wrap_File.cpp
  37. 2 2
      src/modules/filesystem/wrap_FileData.cpp
  38. 13 13
      src/modules/filesystem/wrap_Filesystem.cpp
  39. 2 0
      src/modules/font/GlyphData.cpp
  40. 2 0
      src/modules/font/GlyphData.h
  41. 2 0
      src/modules/font/Rasterizer.cpp
  42. 2 0
      src/modules/font/Rasterizer.h
  43. 11 11
      src/modules/font/wrap_Font.cpp
  44. 2 2
      src/modules/font/wrap_GlyphData.cpp
  45. 3 3
      src/modules/font/wrap_Rasterizer.cpp
  46. 32 0
      src/modules/graphics/Drawable.cpp
  47. 2 0
      src/modules/graphics/Drawable.h
  48. 2 0
      src/modules/graphics/Graphics.cpp
  49. 2 0
      src/modules/graphics/Graphics.h
  50. 2 0
      src/modules/graphics/ParticleSystem.cpp
  51. 3 0
      src/modules/graphics/ParticleSystem.h
  52. 2 0
      src/modules/graphics/Quad.cpp
  53. 2 0
      src/modules/graphics/Quad.h
  54. 1 0
      src/modules/graphics/Texture.cpp
  55. 2 0
      src/modules/graphics/Texture.h
  56. 1 0
      src/modules/graphics/opengl/Canvas.cpp
  57. 2 0
      src/modules/graphics/opengl/Canvas.h
  58. 7 6
      src/modules/graphics/opengl/Font.cpp
  59. 3 1
      src/modules/graphics/opengl/Font.h
  60. 2 0
      src/modules/graphics/opengl/Image.cpp
  61. 2 0
      src/modules/graphics/opengl/Image.h
  62. 2 0
      src/modules/graphics/opengl/Mesh.cpp
  63. 2 0
      src/modules/graphics/opengl/Mesh.h
  64. 1 0
      src/modules/graphics/opengl/Shader.cpp
  65. 2 0
      src/modules/graphics/opengl/Shader.h
  66. 2 0
      src/modules/graphics/opengl/SpriteBatch.cpp
  67. 2 0
      src/modules/graphics/opengl/SpriteBatch.h
  68. 2 0
      src/modules/graphics/opengl/Text.cpp
  69. 2 0
      src/modules/graphics/opengl/Text.h
  70. 2 0
      src/modules/graphics/opengl/Video.cpp
  71. 2 0
      src/modules/graphics/opengl/Video.h
  72. 2 2
      src/modules/graphics/opengl/wrap_Canvas.cpp
  73. 2 2
      src/modules/graphics/opengl/wrap_Font.cpp
  74. 46 46
      src/modules/graphics/opengl/wrap_Graphics.cpp
  75. 4 4
      src/modules/graphics/opengl/wrap_Image.cpp
  76. 6 6
      src/modules/graphics/opengl/wrap_Mesh.cpp
  77. 8 8
      src/modules/graphics/opengl/wrap_ParticleSystem.cpp
  78. 4 4
      src/modules/graphics/opengl/wrap_Shader.cpp
  79. 9 9
      src/modules/graphics/opengl/wrap_SpriteBatch.cpp
  80. 8 8
      src/modules/graphics/opengl/wrap_Text.cpp
  81. 6 6
      src/modules/graphics/opengl/wrap_Video.cpp
  82. 2 2
      src/modules/graphics/wrap_Quad.cpp
  83. 2 2
      src/modules/graphics/wrap_Texture.cpp
  84. 2 0
      src/modules/image/CompressedImageData.cpp
  85. 2 0
      src/modules/image/CompressedImageData.h
  86. 32 0
      src/modules/image/Image.cpp
  87. 2 0
      src/modules/image/Image.h
  88. 2 0
      src/modules/image/ImageData.cpp
  89. 2 0
      src/modules/image/ImageData.h
  90. 2 2
      src/modules/image/wrap_CompressedImageData.cpp
  91. 4 4
      src/modules/image/wrap_Image.cpp
  92. 4 4
      src/modules/image/wrap_ImageData.cpp
  93. 2 0
      src/modules/joystick/Joystick.cpp
  94. 2 0
      src/modules/joystick/Joystick.h
  95. 2 2
      src/modules/joystick/wrap_Joystick.cpp
  96. 2 2
      src/modules/joystick/wrap_JoystickModule.cpp
  97. 1 1
      src/modules/keyboard/wrap_Keyboard.cpp
  98. 2 0
      src/modules/math/BezierCurve.cpp
  99. 2 0
      src/modules/math/BezierCurve.h
  100. 2 0
      src/modules/math/CompressedData.cpp

+ 5 - 0
CMakeLists.txt

@@ -256,6 +256,7 @@ set(LOVE_SRC_COMMON
 	src/common/b64.cpp
 	src/common/b64.h
 	src/common/config.h
+	src/common/Data.cpp
 	src/common/Data.h
 	src/common/delay.cpp
 	src/common/delay.h
@@ -280,6 +281,8 @@ set(LOVE_SRC_COMMON
 	src/common/Reference.h
 	src/common/runtime.cpp
 	src/common/runtime.h
+	src/common/Stream.cpp
+	src/common/Stream.h
 	src/common/StringMap.h
 	src/common/types.cpp
 	src/common/types.h
@@ -459,6 +462,7 @@ source_group("modules\\font\\freetype" FILES ${LOVE_SRC_MODULE_FONT_FREETYPE})
 
 set(LOVE_SRC_MODULE_GRAPHICS_ROOT
 	src/modules/graphics/Color.h
+	src/modules/graphics/Drawable.cpp
 	src/modules/graphics/Drawable.h
 	src/modules/graphics/Graphics.cpp
 	src/modules/graphics/Graphics.h
@@ -540,6 +544,7 @@ source_group("modules\\graphics\\opengl" FILES ${LOVE_SRC_MODULE_GRAPHICS_OPENGL
 set(LOVE_SRC_MODULE_IMAGE_ROOT
 	src/modules/image/CompressedImageData.cpp
 	src/modules/image/CompressedImageData.h
+	src/modules/image/Image.cpp
 	src/modules/image/Image.h
 	src/modules/image/ImageData.cpp
 	src/modules/image/ImageData.h

+ 29 - 0
src/common/Data.cpp

@@ -0,0 +1,29 @@
+/**
+ * Copyright (c) 2006-2016 LOVE Development Team
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.  In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ *    claim that you wrote the original software. If you use this software
+ *    in a product, an acknowledgment in the product documentation would be
+ *    appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ *    misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ **/
+
+// LOVE
+#include "Data.h"
+
+namespace love
+{
+
+love::Type Data::type("Data", &Object::type);
+
+} // love

+ 2 - 0
src/common/Data.h

@@ -38,6 +38,8 @@ class Data : public Object
 {
 public:
 
+	static love::Type type;
+
 	/**
 	 * Destructor.
 	 **/

+ 1 - 0
src/common/Module.cpp

@@ -58,6 +58,7 @@ namespace
 namespace love
 {
 
+love::Type Module::type("Module", &Object::type);
 Module *Module::instances[] = {};
 
 Module::~Module()

+ 2 - 0
src/common/Module.h

@@ -34,6 +34,8 @@ class Module : public Object
 {
 public:
 
+	static love::Type type;
+
 	enum ModuleType
 	{
 		M_AUDIO,

+ 2 - 0
src/common/Object.cpp

@@ -24,6 +24,8 @@
 namespace love
 {
 
+love::Type Object::type("Object", nullptr);
+
 Object::Object()
 	: count(1)
 {

+ 3 - 0
src/common/Object.h

@@ -22,6 +22,7 @@
 #define LOVE_OBJECT_H
 
 #include <atomic>
+#include "types.h"
 
 namespace love
 {
@@ -38,6 +39,8 @@ class Object
 {
 public:
 
+	static love::Type type;
+
 	/**
 	 * Constructor. Sets reference count to one.
 	 **/

+ 29 - 0
src/common/Stream.cpp

@@ -0,0 +1,29 @@
+/**
+ * Copyright (c) 2006-2015 LOVE Development Team
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.  In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ *    claim that you wrote the original software. If you use this software
+ *    in a product, an acknowledgment in the product documentation would be
+ *    appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ *    misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ **/
+
+// LOVE
+#include "Stream.h"
+
+namespace love
+{
+
+love::Type Stream::type("Stream", &Object::type);
+
+} // love

+ 2 - 0
src/common/Stream.h

@@ -31,6 +31,8 @@ namespace love
 class Stream : public Object
 {
 public:
+	static love::Type type;
+
 	virtual ~Stream() {}
 
 	// getData and getSize are assumed to talk about

+ 8 - 8
src/common/Variant.cpp

@@ -24,19 +24,19 @@
 namespace love
 {
 
-static love::Type extractudatatype(lua_State *L, int idx)
+static love::Type *extractudatatype(lua_State *L, int idx)
 {
 	Proxy *u = (Proxy *)lua_touserdata(L, idx);
 
-	if (u == nullptr || u->type <= INVALID_ID || u->type >= TYPE_MAX_ENUM)
-		return INVALID_ID;
+	if (u == nullptr || u->type == nullptr)
+		return nullptr;
 
 	// We could get rid of the dynamic_cast for more performance, but it would
 	// be less safe...
 	if (dynamic_cast<Object *>(u->object) != nullptr)
 		return u->type;
 
-	return INVALID_ID;
+	return nullptr;
 }
 
 Variant::Variant()
@@ -77,11 +77,11 @@ Variant::Variant(void *userdata)
 	data.userdata = userdata;
 }
 
-Variant::Variant(love::Type udatatype, void *userdata)
+Variant::Variant(love::Type *udatatype, void *userdata)
 	: type(FUSERDATA)
 	, udatatype(udatatype)
 {
-	if (udatatype != INVALID_ID)
+	if (udatatype != nullptr)
 	{
 		Proxy *p = (Proxy *) userdata;
 		data.userdata = p->object;
@@ -243,8 +243,8 @@ void Variant::toLua(lua_State *L) const
 		lua_pushlightuserdata(L, data.userdata);
 		break;
 	case FUSERDATA:
-		if (udatatype != INVALID_ID)
-			luax_pushtype(L, udatatype, (love::Object *) data.userdata);
+		if (udatatype != nullptr)
+			luax_pushtype(L, *udatatype, (love::Object *) data.userdata);
 		else
 			lua_pushlightuserdata(L, data.userdata);
 		// I know this is not the same

+ 2 - 2
src/common/Variant.h

@@ -53,7 +53,7 @@ public:
 	Variant(double number);
 	Variant(const char *string, size_t len);
 	Variant(void *userdata);
-	Variant(love::Type udatatype, void *userdata);
+	Variant(love::Type *udatatype, void *userdata);
 	Variant(std::vector<std::pair<Variant, Variant>> *table);
 	Variant(const Variant &v);
 	Variant(Variant &&v);
@@ -101,7 +101,7 @@ private:
 	static const int MAX_SMALL_STRING_LENGTH = 15;
 
 	Type type;
-	love::Type udatatype;
+	love::Type *udatatype;
 
 	union Data
 	{

+ 28 - 33
src/common/runtime.cpp

@@ -67,8 +67,11 @@ static int w__type(lua_State *L)
 static int w__typeOf(lua_State *L)
 {
 	Proxy *p = (Proxy *)lua_touserdata(L, 1);
-	Type t = luax_type(L, 2);
-	luax_pushboolean(L, typeFlags[p->type][t]);
+	Type *t = luax_type(L, 2);
+	if (!t)
+		luax_pushboolean(L, false);
+	else
+		luax_pushboolean(L, p->type->isa(*t));
 	return 1;
 }
 
@@ -248,7 +251,7 @@ int luax_require(lua_State *L, const char *name)
 
 int luax_register_module(lua_State *L, const WrappedModule &m)
 {
-	love::addTypeName(m.type, m.name);
+	m.type->init();
 
 	// Put a reference to the C++ module in Lua.
 	luax_insistregistry(L, REGISTRY_MODULES);
@@ -304,9 +307,9 @@ int luax_preload(lua_State *L, lua_CFunction f, const char *name)
 	return 0;
 }
 
-int luax_register_type(lua_State *L, love::Type type, const char *name, ...)
+int luax_register_type(lua_State *L, love::Type *type, ...)
 {
-	love::addTypeName(type, name);
+	type->init();
 
 	// Get the place for storing and re-using instantiated love types.
 	luax_getregistry(L, REGISTRY_OBJECTS);
@@ -333,7 +336,7 @@ int luax_register_type(lua_State *L, love::Type type, const char *name, ...)
 	else
 		lua_pop(L, 1);
 
-	luaL_newmetatable(L, name);
+	luaL_newmetatable(L, type->getName());
 
 	// m.__index = m
 	lua_pushvalue(L, -1);
@@ -348,12 +351,12 @@ int luax_register_type(lua_State *L, love::Type type, const char *name, ...)
 	lua_setfield(L, -2, "__eq");
 
 	// Add tostring function.
-	lua_pushstring(L, name);
+	lua_pushstring(L, type->getName());
 	lua_pushcclosure(L, w__tostring, 1);
 	lua_setfield(L, -2, "__tostring");
 
 	// Add type
-	lua_pushstring(L, name);
+	lua_pushstring(L, type->getName());
 	lua_pushcclosure(L, w__type, 1);
 	lua_setfield(L, -2, "type");
 
@@ -366,7 +369,7 @@ int luax_register_type(lua_State *L, love::Type type, const char *name, ...)
 	lua_setfield(L, -2, "release");
 
 	va_list fs;
-	va_start(fs, name);
+	va_start(fs, type);
 	for (const luaL_Reg *f = va_arg(fs, const luaL_Reg *); f; f = va_arg(fs, const luaL_Reg *))
 		luax_setfuncs(L, f);
 	va_end(fs);
@@ -375,13 +378,10 @@ int luax_register_type(lua_State *L, love::Type type, const char *name, ...)
 	return 0;
 }
 
-void luax_gettypemetatable(lua_State *L, love::Type type)
+void luax_gettypemetatable(lua_State *L, love::Type &type)
 {
-	const char *name = nullptr;
-	if (getTypeName(type, name))
-		lua_getfield(L, LUA_REGISTRYINDEX, name);
-	else
-		lua_pushnil(L);
+	const char *name = type.getName();
+	lua_getfield(L, LUA_REGISTRYINDEX, name);
 }
 
 int luax_table_insert(lua_State *L, int tindex, int vindex, int pos)
@@ -437,23 +437,21 @@ int luax_register_searcher(lua_State *L, lua_CFunction f, int pos)
 	return 0;
 }
 
-void luax_rawnewtype(lua_State *L, love::Type type, love::Object *object)
+void luax_rawnewtype(lua_State *L, love::Type &type, love::Object *object)
 {
 	Proxy *u = (Proxy *)lua_newuserdata(L, sizeof(Proxy));
 
 	object->retain();
 
 	u->object = object;
-	u->type = type;
-
-	const char *name = "Invalid";
-	getTypeName(type, name);
+	u->type = &type;
 
+	const char *name = type.getName();
 	luaL_newmetatable(L, name);
 	lua_setmetatable(L, -2);
 }
 
-void luax_pushtype(lua_State *L, love::Type type, love::Object *object)
+void luax_pushtype(lua_State *L, love::Type &type, love::Object *object)
 {
 	if (object == nullptr)
 	{
@@ -495,15 +493,15 @@ void luax_pushtype(lua_State *L, love::Type type, love::Object *object)
 	// Keep the Proxy userdata on the stack.
 }
 
-bool luax_istype(lua_State *L, int idx, love::Type type)
+bool luax_istype(lua_State *L, int idx, love::Type &type)
 {
 	if (lua_type(L, idx) != LUA_TUSERDATA)
 		return false;
 
 	Proxy *p = (Proxy *) lua_touserdata(L, idx);
 
-	if (p->type > INVALID_ID && p->type < TYPE_MAX_ENUM)
-		return typeFlags[p->type][type];
+	if (p->type != nullptr)
+		return p->type->isa(type);
 	else
 		return false;
 }
@@ -705,7 +703,7 @@ lua_State *luax_getpinnedthread(lua_State *L)
 extern "C" int luax_typerror(lua_State *L, int narg, const char *tname)
 {
 	int argtype = lua_type(L, narg);
-	const char *argtname = 0;
+	const char *argtname = nullptr;
 
 	// We want to use the love type name for userdata, if possible.
 	if (argtype == LUA_TUSERDATA && luaL_getmetafield(L, narg, "type") != 0)
@@ -717,13 +715,12 @@ extern "C" int luax_typerror(lua_State *L, int narg, const char *tname)
 
 			// Non-love userdata might have a type metamethod which doesn't
 			// describe its type properly, so we only use it for love types.
-			love::Type t;
-			if (!love::getTypeName(argtname, t))
-				argtname = 0;
+			if (!Type::byName(argtname))
+				argtname = nullptr;
 		}
 	}
 
-	if (argtname == 0)
+	if (argtname == nullptr)
 		argtname = lua_typename(L, argtype);
 
 	const char *msg = lua_pushfstring(L, "%s expected, got %s", tname, argtname);
@@ -752,11 +749,9 @@ void luax_register(lua_State *L, const char *name, const luaL_Reg *l)
 	}
 }
 
-Type luax_type(lua_State *L, int idx)
+Type *luax_type(lua_State *L, int idx)
 {
-	Type t = INVALID_ID;
-	getTypeName(luaL_checkstring(L, idx), t);
-	return t;
+	return Type::byName(luaL_checkstring(L, idx));
 }
 
 } // love

+ 60 - 24
src/common/runtime.h

@@ -43,6 +43,9 @@ class Object;
 class Module;
 class Reference;
 
+template<typename T>
+class StrongRef;
+
 /**
  * Registries represent special tables which can be accessed with
  * luax_insistregistry and luax_getregistry.
@@ -62,7 +65,7 @@ enum Registry
 struct Proxy
 {
 	// Holds type information (see types.h).
-	Type type;
+	love::Type *type;
 
 	// Pointer to the actual object.
 	Object *object;
@@ -80,7 +83,7 @@ struct WrappedModule
 	const char *name;
 
 	// The type of this module.
-	love::Type type;
+	love::Type *type;
 
 	// The functions of the module (last element {0,0}).
 	const luaL_Reg *functions;
@@ -246,16 +249,17 @@ int luax_preload(lua_State *L, lua_CFunction f, const char *name);
 
 /**
  * Register a new type.
+ * NOTE: The type is passed by pointer instead of reference because calling va_start
+ * on a reference is undefined behaviour.
  * @param type The type.
- * @param name The type's human-readable name
  * @param ... The list of lists of member functions for the type. (of type luaL_Reg*)
  **/
-int luax_register_type(lua_State *L, love::Type type, const char *name, ...);
+int luax_register_type(lua_State *L, love::Type *type, ...);
 
 /**
  * Pushes the metatable of the specified type onto the stack.
 **/
-void luax_gettypemetatable(lua_State *L, love::Type type);
+void luax_gettypemetatable(lua_State *L, love::Type &type);
 
 /**
  * Do a table.insert from C
@@ -283,7 +287,19 @@ int luax_register_searcher(lua_State *L, lua_CFunction f, int pos = -1);
  * @param type The type information of the object.
  * @param object The pointer to the actual object.
  **/
-void luax_pushtype(lua_State *L, const love::Type type, love::Object *object);
+void luax_pushtype(lua_State *L, love::Type &type, love::Object *object);
+
+template <typename T>
+void luax_pushtype(lua_State *L, T *object)
+{
+	luax_pushtype(L, T::type, object);
+}
+
+template <typename T>
+void luax_pushtype(lua_State *L, StrongRef<T> &object)
+{
+	luax_pushtype(L, T::type, object);
+}
 
 /**
  * Creates a new Lua representation of the given object *without* checking if it
@@ -296,7 +312,7 @@ void luax_pushtype(lua_State *L, const love::Type type, love::Object *object);
  * @param type The type information of the object.
  * @param object The pointer to the actual object.
  **/
-void luax_rawnewtype(lua_State *L, love::Type type, love::Object *object);
+void luax_rawnewtype(lua_State *L, love::Type &type, love::Object *object);
 
 /**
  * Checks whether the value at idx is a certain type.
@@ -305,7 +321,7 @@ void luax_rawnewtype(lua_State *L, love::Type type, love::Object *object);
  * @param type The type to check for.
  * @return True if the value is Proxy of the specified type, false otherwise.
  **/
-bool luax_istype(lua_State *L, int idx, love::Type type);
+bool luax_istype(lua_State *L, int idx, love::Type &type);
 
 /**
  * Gets the function love.module.function and puts it on top of the stack (alone). If the
@@ -434,21 +450,19 @@ extern "C" { // Called by enet and luasocket
  * @param type The type bit.
  **/
 template <typename T>
-T *luax_checktype(lua_State *L, int idx, love::Type type)
+T *luax_checktype(lua_State *L, int idx, love::Type &type)
 {
 	if (lua_type(L, idx) != LUA_TUSERDATA)
 	{
-		const char *name = "Invalid";
-		getTypeName(type, name);
+		const char *name = type.getName();
 		luax_typerror(L, idx, name);
 	}
 
 	Proxy *u = (Proxy *)lua_touserdata(L, idx);
 
-	if (u->type <= INVALID_ID || u->type >= TYPE_MAX_ENUM || !typeFlags[u->type][type])
+	if (u->type == nullptr || !u->type->isa(type))
 	{
-		const char *name = "Invalid";
-		getTypeName(type, name);
+		const char *name = type.getName();
 		luax_typerror(L, idx, name);
 	}
 
@@ -459,10 +473,15 @@ T *luax_checktype(lua_State *L, int idx, love::Type type)
 }
 
 template <typename T>
-T *luax_getmodule(lua_State *L, love::Type type)
+T *luax_checktype(lua_State *L, int idx)
+{
+	return luax_checktype<T>(L, idx, T::type);
+}
+
+template <typename T>
+T *luax_getmodule(lua_State *L, love::Type &type)
 {
-	const char *name = "Invalid";
-	getTypeName(type, name);
+	const char *name = type.getName();
 
 	luax_insistregistry(L, REGISTRY_MODULES);
 	lua_getfield(L, -1, name);
@@ -472,7 +491,7 @@ T *luax_getmodule(lua_State *L, love::Type type)
 
 	Proxy *u = (Proxy *)lua_touserdata(L, -1);
 
-	if (u->type <= INVALID_ID || u->type >= TYPE_MAX_ENUM || !typeFlags[u->type][type])
+	if (u->type == nullptr || !u->type->isa(type))
 		luaL_error(L, "Incorrect module %s", name);
 
 	lua_pop(L, 2);
@@ -481,10 +500,15 @@ T *luax_getmodule(lua_State *L, love::Type type)
 }
 
 template <typename T>
-T *luax_optmodule(lua_State *L, love::Type type)
+T *luax_getmodule(lua_State *L)
 {
-	const char *name = "Invalid";
-	getTypeName(type, name);
+	return luax_getmodule<T>(L, T::type);
+}
+
+template <typename T>
+T *luax_optmodule(lua_State *L, love::Type &type)
+{
+	const char *name = type.getName();
 
 	luax_insistregistry(L, REGISTRY_MODULES);
 	lua_getfield(L, -1, name);
@@ -497,7 +521,7 @@ T *luax_optmodule(lua_State *L, love::Type type)
 
 	Proxy *u = (Proxy *)lua_touserdata(L, -1);
 
-	if (!typeFlags[u->type][type])
+	if (!u->type->isa(type))
 		luaL_error(L, "Incorrect module %s", name);
 
 	lua_pop(L, 2);
@@ -505,6 +529,12 @@ T *luax_optmodule(lua_State *L, love::Type type)
 	return (T *) u->object;
 }
 
+template <typename T>
+T *luax_optmodule(lua_State *L)
+{
+	return luax_optmodule<T>(L, T::type);
+}
+
 /**
  * Converts the value at idx to the specified type without checking that
  * this conversion is valid. If the type has been previously verified with
@@ -514,7 +544,7 @@ T *luax_optmodule(lua_State *L, love::Type type)
  * @param type The type of the object.
  **/
 template <typename T>
-T *luax_totype(lua_State *L, int idx, love::Type /*type*/)
+T *luax_totype(lua_State *L, int idx, love::Type& /*type*/)
 {
 	T *o = (T *)(((Proxy *)lua_touserdata(L, idx))->object);
 
@@ -524,7 +554,13 @@ T *luax_totype(lua_State *L, int idx, love::Type /*type*/)
 	return o;
 }
 
-Type luax_type(lua_State *L, int idx);
+template <typename T>
+T *luax_totype(lua_State *L, int idx)
+{
+	return luax_totype<T>(L, idx, T::type);
+}
+
+Type *luax_type(lua_State *L, int idx);
 
 /**
  * Converts any exceptions thrown by the passed lambda function into a Lua error.

+ 41 - 106
src/common/types.cpp

@@ -18,128 +18,63 @@
  * 3. This notice may not be removed or altered from any source distribution.
  **/
 
+// STL
+#include <unordered_map>
+
 #include "types.h"
-#include "StringMap.h"
 
 namespace love
 {
 
-static const TypeBits *createTypeFlags()
-{
-	static TypeBits b[TYPE_MAX_ENUM];
-	TypeBits one = TypeBits(1);
-
-	b[INVALID_ID] = one << INVALID_ID;
-
-	b[OBJECT_ID] = one << OBJECT_ID;
-	b[DATA_ID] = (one << DATA_ID) | b[OBJECT_ID];
-	b[MODULE_ID] = (one << MODULE_ID) | b[OBJECT_ID];
-	b[STREAM_ID] = (one << STREAM_ID) | b[OBJECT_ID];
-
-	// Filesystem.
-	b[FILESYSTEM_FILE_ID] = (one << FILESYSTEM_FILE_ID) | b[OBJECT_ID];
-	b[FILESYSTEM_DROPPED_FILE_ID] = (one << FILESYSTEM_DROPPED_FILE_ID) | b[FILESYSTEM_FILE_ID];
-	b[FILESYSTEM_FILE_DATA_ID] = (one << FILESYSTEM_FILE_DATA_ID) | b[DATA_ID];
-
-	b[FONT_GLYPH_DATA_ID] = (one << FONT_GLYPH_DATA_ID) | b[DATA_ID];
-	b[FONT_RASTERIZER_ID] = (one << FONT_RASTERIZER_ID) | b[OBJECT_ID];
-
-	// Graphics.
-	b[GRAPHICS_DRAWABLE_ID] = (one << GRAPHICS_DRAWABLE_ID) | b[OBJECT_ID];
-	b[GRAPHICS_TEXTURE_ID] = (one << GRAPHICS_TEXTURE_ID) | b[GRAPHICS_DRAWABLE_ID];
-	b[GRAPHICS_IMAGE_ID] = (one << GRAPHICS_IMAGE_ID) | b[GRAPHICS_TEXTURE_ID];
-	b[GRAPHICS_QUAD_ID] = (one << GRAPHICS_QUAD_ID) | b[OBJECT_ID];
-	b[GRAPHICS_FONT_ID] = (one << GRAPHICS_FONT_ID) | b[OBJECT_ID];
-	b[GRAPHICS_PARTICLE_SYSTEM_ID] = (one << GRAPHICS_PARTICLE_SYSTEM_ID) | b[GRAPHICS_DRAWABLE_ID];
-	b[GRAPHICS_SPRITE_BATCH_ID] = (one << GRAPHICS_SPRITE_BATCH_ID) | b[GRAPHICS_DRAWABLE_ID];
-	b[GRAPHICS_CANVAS_ID] = (one << GRAPHICS_CANVAS_ID) | b[GRAPHICS_TEXTURE_ID];
-	b[GRAPHICS_SHADER_ID] = (one << GRAPHICS_SHADER_ID) | b[OBJECT_ID];
-	b[GRAPHICS_MESH_ID] = (one << GRAPHICS_MESH_ID) | b[GRAPHICS_DRAWABLE_ID];
-	b[GRAPHICS_TEXT_ID] = (one << GRAPHICS_TEXT_ID) | b[GRAPHICS_DRAWABLE_ID];
-	b[GRAPHICS_VIDEO_ID] = (one << GRAPHICS_VIDEO_ID) | b[GRAPHICS_DRAWABLE_ID];
-
-	// Image.
-	b[IMAGE_IMAGE_DATA_ID] = (one << IMAGE_IMAGE_DATA_ID) | b[DATA_ID];
-	b[IMAGE_COMPRESSED_IMAGE_DATA_ID] = (one << IMAGE_COMPRESSED_IMAGE_DATA_ID) | b[DATA_ID];
-
-	// Joystick.
-	b[JOYSTICK_JOYSTICK_ID] = (one << JOYSTICK_JOYSTICK_ID) | b[OBJECT_ID];
-
-	// Math.
-	b[MATH_RANDOM_GENERATOR_ID] = (one << MATH_RANDOM_GENERATOR_ID) | b[OBJECT_ID];
-	b[MATH_BEZIER_CURVE_ID] = (one << MATH_BEZIER_CURVE_ID) | b[OBJECT_ID];
-	b[MATH_COMPRESSED_DATA_ID] = (one << MATH_COMPRESSED_DATA_ID) | b[DATA_ID];
-	b[MATH_TRANSFORM_ID] = (one << MATH_TRANSFORM_ID) | b[OBJECT_ID];
-
-	// Audio.
-	b[AUDIO_SOURCE_ID] = (one << AUDIO_SOURCE_ID) | b[OBJECT_ID];
-	b[AUDIO_RECORDING_DEVICE_ID] = (one << AUDIO_RECORDING_DEVICE_ID) | b[OBJECT_ID];
+static std::unordered_map<std::string, Type*> types;
 
-	// Sound.
-	b[SOUND_SOUND_DATA_ID] = (one << SOUND_SOUND_DATA_ID) | b[DATA_ID];
-	b[SOUND_DECODER_ID] = one << SOUND_DECODER_ID;
-
-	// Mouse.
-	b[MOUSE_CURSOR_ID] = (one << MOUSE_CURSOR_ID) | b[OBJECT_ID];
-
-	// Physics.
-	b[PHYSICS_WORLD_ID] = (one << PHYSICS_WORLD_ID) | b[OBJECT_ID];
-	b[PHYSICS_CONTACT_ID] = (one << PHYSICS_CONTACT_ID) | b[OBJECT_ID];
-	b[PHYSICS_BODY_ID] = (one << PHYSICS_BODY_ID) | b[OBJECT_ID];
-	b[PHYSICS_FIXTURE_ID] = (one << PHYSICS_FIXTURE_ID) | b[OBJECT_ID];
-	b[PHYSICS_SHAPE_ID] = (one << PHYSICS_SHAPE_ID) | b[OBJECT_ID];
-	b[PHYSICS_CIRCLE_SHAPE_ID] = (one << PHYSICS_CIRCLE_SHAPE_ID) | b[PHYSICS_SHAPE_ID];
-	b[PHYSICS_POLYGON_SHAPE_ID] = (one << PHYSICS_POLYGON_SHAPE_ID) | b[PHYSICS_SHAPE_ID];
-	b[PHYSICS_EDGE_SHAPE_ID] = (one << PHYSICS_EDGE_SHAPE_ID) | b[PHYSICS_SHAPE_ID];
-	b[PHYSICS_CHAIN_SHAPE_ID] = (one << PHYSICS_CHAIN_SHAPE_ID) | b[PHYSICS_SHAPE_ID];
-	b[PHYSICS_JOINT_ID] = (one << PHYSICS_JOINT_ID) | b[OBJECT_ID];
-	b[PHYSICS_MOUSE_JOINT_ID] = (one << PHYSICS_MOUSE_JOINT_ID) | b[PHYSICS_JOINT_ID];
-	b[PHYSICS_DISTANCE_JOINT_ID] = (one << PHYSICS_DISTANCE_JOINT_ID) | b[PHYSICS_JOINT_ID];
-	b[PHYSICS_PRISMATIC_JOINT_ID] = (one << PHYSICS_PRISMATIC_JOINT_ID) | b[PHYSICS_JOINT_ID];
-	b[PHYSICS_REVOLUTE_JOINT_ID] = (one << PHYSICS_REVOLUTE_JOINT_ID) | b[PHYSICS_JOINT_ID];
-	b[PHYSICS_PULLEY_JOINT_ID] = (one << PHYSICS_PULLEY_JOINT_ID) | b[PHYSICS_JOINT_ID];
-	b[PHYSICS_GEAR_JOINT_ID] = (one << PHYSICS_GEAR_JOINT_ID) | b[PHYSICS_JOINT_ID];
-	b[PHYSICS_FRICTION_JOINT_ID] = (one << PHYSICS_FRICTION_JOINT_ID) | b[PHYSICS_JOINT_ID];
-	b[PHYSICS_WELD_JOINT_ID] = (one << PHYSICS_WELD_JOINT_ID) | b[PHYSICS_JOINT_ID];
-	b[PHYSICS_ROPE_JOINT_ID] = (one << PHYSICS_ROPE_JOINT_ID) | b[PHYSICS_JOINT_ID];
-	b[PHYSICS_WHEEL_JOINT_ID] = (one << PHYSICS_WHEEL_JOINT_ID) | b[PHYSICS_JOINT_ID];
-	b[PHYSICS_MOTOR_JOINT_ID] = (one << PHYSICS_MOTOR_JOINT_ID) | b[PHYSICS_JOINT_ID];
-
-	// Thread.
-	b[THREAD_THREAD_ID] = (one << THREAD_THREAD_ID) | b[OBJECT_ID];
-	b[THREAD_CHANNEL_ID] = (one << THREAD_CHANNEL_ID) | b[OBJECT_ID];
-
-	// Video
-	b[VIDEO_VIDEO_STREAM_ID] = (one << VIDEO_VIDEO_STREAM_ID) | b[STREAM_ID];
-
-	// Modules.
-	b[MODULE_FILESYSTEM_ID] = (one << MODULE_FILESYSTEM_ID) | b[MODULE_ID];
-	b[MODULE_GRAPHICS_ID] = (one << MODULE_GRAPHICS_ID) | b[MODULE_ID];
-	b[MODULE_IMAGE_ID] = (one << MODULE_IMAGE_ID) | b[MODULE_ID];
-	b[MODULE_SOUND_ID] = (one << MODULE_SOUND_ID) | b[MODULE_ID];
-
-	return b;
+Type::Type(const char *name, Type *parent)
+	: name(name)
+	, parent(parent)
+	, id(0)
+	, inited(false)
+{
 }
 
-const TypeBits *typeFlags = createTypeFlags();
-
-static StringMap<Type, TYPE_MAX_ENUM> types(nullptr, 0);
+void Type::init()
+{
+	static uint32 nextId = 1;
+
+	// Make sure we don't init twice, that would be bad
+	if (inited)
+		return;
+
+	// Note: we add it here, not in the constructor, because some Types can get initialized before the map!
+	types[name] = this;
+	id = nextId++;
+	bits[id] = true;
+	inited = true;
+
+	if (!parent)
+		return;
+	if (!parent->inited)
+		parent->init();
+	bits |= parent->bits;
+}
 
-void addTypeName(Type type, const char *name)
+uint32 Type::getId()
 {
-	const char *n;
-	if (!types.find(type, n))
-		types.add(name, type);
+	if (!inited)
+		init();
+	return id;
 }
 
-bool getTypeName(const char *in, love::Type &out)
+const char *Type::getName() const
 {
-	return types.find(in, out);
+	return name;
 }
 
-bool getTypeName(love::Type in, const char *&out)
+Type *Type::byName(const char *name)
 {
-	return types.find(in, out);
+	auto pos = types.find(name);
+	if (pos == types.end())
+		return nullptr;
+	return pos->second;
 }
 
 } // love

+ 39 - 104
src/common/types.h

@@ -21,119 +21,54 @@
 #ifndef LOVE_TYPES_H
 #define LOVE_TYPES_H
 
+#include "int.h"
+
 // STD
 #include <bitset>
+#include <vector>
 
 namespace love
 {
 
-enum Type
+class Type
 {
-	INVALID_ID = 0,
-	// Cross-module types.
-	OBJECT_ID,
-	DATA_ID,
-	MODULE_ID,
-	STREAM_ID,
-
-	// Filesystem.
-	FILESYSTEM_FILE_ID,
-	FILESYSTEM_DROPPED_FILE_ID,
-	FILESYSTEM_FILE_DATA_ID,
-
-	// Font
-	FONT_GLYPH_DATA_ID,
-	FONT_RASTERIZER_ID,
-
-	// Graphics
-	GRAPHICS_DRAWABLE_ID,
-	GRAPHICS_TEXTURE_ID,
-	GRAPHICS_IMAGE_ID,
-	GRAPHICS_QUAD_ID,
-	GRAPHICS_FONT_ID,
-	GRAPHICS_PARTICLE_SYSTEM_ID,
-	GRAPHICS_SPRITE_BATCH_ID,
-	GRAPHICS_CANVAS_ID,
-	GRAPHICS_SHADER_ID,
-	GRAPHICS_MESH_ID,
-	GRAPHICS_TEXT_ID,
-	GRAPHICS_VIDEO_ID,
-
-	// Image
-	IMAGE_IMAGE_DATA_ID,
-	IMAGE_COMPRESSED_IMAGE_DATA_ID,
-
-	// Joystick
-	JOYSTICK_JOYSTICK_ID,
-
-	// Math
-	MATH_RANDOM_GENERATOR_ID,
-	MATH_BEZIER_CURVE_ID,
-	MATH_COMPRESSED_DATA_ID,
-	MATH_TRANSFORM_ID,
-
-	// Audio
-	AUDIO_SOURCE_ID,
-	AUDIO_RECORDING_DEVICE_ID,
-
-	// Sound
-	SOUND_SOUND_DATA_ID,
-	SOUND_DECODER_ID,
-
-	// Mouse
-	MOUSE_CURSOR_ID,
-
-	// Physics
-	PHYSICS_WORLD_ID,
-	PHYSICS_CONTACT_ID,
-	PHYSICS_BODY_ID,
-	PHYSICS_FIXTURE_ID,
-	PHYSICS_SHAPE_ID,
-	PHYSICS_CIRCLE_SHAPE_ID,
-	PHYSICS_POLYGON_SHAPE_ID,
-	PHYSICS_EDGE_SHAPE_ID,
-	PHYSICS_CHAIN_SHAPE_ID,
-	PHYSICS_JOINT_ID,
-	PHYSICS_MOUSE_JOINT_ID,
-	PHYSICS_DISTANCE_JOINT_ID,
-	PHYSICS_PRISMATIC_JOINT_ID,
-	PHYSICS_REVOLUTE_JOINT_ID,
-	PHYSICS_PULLEY_JOINT_ID,
-	PHYSICS_GEAR_JOINT_ID,
-	PHYSICS_FRICTION_JOINT_ID,
-	PHYSICS_WELD_JOINT_ID,
-	PHYSICS_ROPE_JOINT_ID,
-	PHYSICS_WHEEL_JOINT_ID,
-	PHYSICS_MOTOR_JOINT_ID,
-
-	// Thread
-	THREAD_THREAD_ID,
-	THREAD_CHANNEL_ID,
-
-	// Video
-	VIDEO_VIDEO_STREAM_ID,
-
-	// The modules themselves. Only add abstracted modules here.
-	MODULE_FILESYSTEM_ID,
-	MODULE_GRAPHICS_ID,
-	MODULE_IMAGE_ID,
-	MODULE_SOUND_ID,
-
-	// Count the number of bits needed.
-	TYPE_MAX_ENUM
+public:
+	static const uint32 MAX_TYPES = 128;
+
+	Type(const char *name, Type *parent);
+	Type(const Type&) = delete;
+
+	static Type *byName(const char *name);
+
+	void init();
+	uint32 getId();
+	const char *getName() const;
+
+	bool isa(const uint32 &other)
+	{
+		if (!inited)
+			init();
+		return bits[other];
+	}
+
+	bool isa(Type &other)
+	{
+		if (!inited)
+			init();
+		// Note that if this type implements the other
+		// calling init above will also have inited
+		// the other.
+		return bits[other.id];
+	}
+
+private:
+	const char * const name;
+	Type * const parent;
+	uint32 id;
+	bool inited;
+	std::bitset<MAX_TYPES> bits;
 };
 
-typedef std::bitset<TYPE_MAX_ENUM> TypeBits;
-
-/**
- * Array of length TYPE_MAX_ENUM containing the flags for each love Type.
- **/
-extern const TypeBits *typeFlags;
-
-void addTypeName(Type type, const char *name);
-bool getTypeName(const char *in, Type &out);
-bool getTypeName(Type in, const char *&out);
-
 } // love
 
 #endif // LOVE_TYPES_H

+ 2 - 2
src/common/wrap_Data.cpp

@@ -25,7 +25,7 @@ namespace love
 
 Data *luax_checkdata(lua_State *L, int idx)
 {
-	return luax_checktype<Data>(L, idx, DATA_ID);
+	return luax_checktype<Data>(L, idx);
 }
 
 int w_Data_getString(lua_State *L)
@@ -59,7 +59,7 @@ const luaL_Reg w_Data_functions[] =
 
 int w_Data_open(lua_State *L)
 {
-	luax_register_type(L, DATA_ID, "Data", w_Data_functions, nullptr);
+	luax_register_type(L, &Data::type, w_Data_functions, nullptr);
 	return 0;
 }
 

+ 2 - 0
src/modules/audio/RecordingDevice.cpp

@@ -25,6 +25,8 @@ namespace love
 namespace audio
 {
 
+love::Type RecordingDevice::type("RecordingDevice", &Object::type);
+
 RecordingDevice::RecordingDevice()
 {
 }

+ 3 - 0
src/modules/audio/RecordingDevice.h

@@ -34,6 +34,9 @@ namespace audio
 class RecordingDevice : public love::Object
 {
 public:
+
+	static love::Type type;
+
 	RecordingDevice();
 	virtual ~RecordingDevice();
 

+ 5 - 3
src/modules/audio/Source.cpp

@@ -25,8 +25,10 @@ namespace love
 namespace audio
 {
 
-Source::Source(Type type)
-	: type(type)
+love::Type Source::type("Source", &Object::type);
+
+Source::Source(Type sourceType)
+	: sourceType(sourceType)
 {
 }
 
@@ -36,7 +38,7 @@ Source::~Source()
 
 Source::Type Source::getType() const
 {
-	return type;
+	return sourceType;
 }
 
 bool Source::getConstant(const char *in, Type &out)

+ 3 - 1
src/modules/audio/Source.h

@@ -34,6 +34,8 @@ class Source : public Object
 {
 public:
 
+	static love::Type type;
+
 	enum Type
 	{
 		TYPE_STATIC,
@@ -114,7 +116,7 @@ public:
 
 protected:
 
-	Type type;
+	Type sourceType;
 
 private:
 

+ 21 - 21
src/modules/audio/openal/Source.cpp

@@ -179,7 +179,7 @@ Source::Source(Pool *pool, int sampleRate, int bitDepth, int channels)
 }
 
 Source::Source(const Source &s)
-	: love::audio::Source(s.type)
+	: love::audio::Source(s.sourceType)
 	, pool(s.pool)
 	, valid(false)
 	, staticBuffer(s.staticBuffer)
@@ -200,14 +200,14 @@ Source::Source(const Source &s)
 	, bitDepth(s.bitDepth)
 	, decoder(nullptr)
 	, toLoop(0)
-	, unusedBufferTop(s.type == TYPE_STREAM ? MAX_BUFFERS - 1 : -1)
+	, unusedBufferTop(s.sourceType == TYPE_STREAM ? MAX_BUFFERS - 1 : -1)
 {
-	if (type == TYPE_STREAM)
+	if (sourceType == TYPE_STREAM)
 	{
 		if (s.decoder.get())
 			decoder.set(s.decoder->clone(), Acquire::NORETAIN);
 	}
-	if (type != TYPE_STATIC)
+	if (sourceType != TYPE_STATIC)
 	{
 		alGenBuffers(MAX_BUFFERS, streamBuffers);
 		for (unsigned int i = 0; i < MAX_BUFFERS; i++)
@@ -224,7 +224,7 @@ Source::~Source()
 	if (valid)
 		pool->stop(this);
 
-	if (type != TYPE_STATIC)
+	if (sourceType != TYPE_STATIC)
 		alDeleteBuffers(MAX_BUFFERS, streamBuffers);
 }
 
@@ -265,7 +265,7 @@ bool Source::isFinished() const
 	if (!valid)
 		return false;
 
-	if (type == TYPE_STREAM && (isLooping() || !decoder->isFinished()))
+	if (sourceType == TYPE_STREAM && (isLooping() || !decoder->isFinished()))
 		return false;
 
 	ALenum state;
@@ -278,7 +278,7 @@ bool Source::update()
 	if (!valid)
 		return false;
 
-	switch (type)
+	switch (sourceType)
 	{
 		case TYPE_STATIC:
 		{
@@ -405,7 +405,7 @@ void Source::seekAtomic(float offset, void *unit)
 	}
 
 	bool wasPlaying = isPlaying();
-	switch (type)
+	switch (sourceType)
 	{
 		case TYPE_STATIC:
 			if (valid)
@@ -459,7 +459,7 @@ void Source::seekAtomic(float offset, void *unit)
 		case TYPE_MAX_ENUM:
 			break;
 	}
-	if (wasPlaying && (alGetError() == AL_INVALID_VALUE || (type == TYPE_STREAM && !isPlaying())))
+	if (wasPlaying && (alGetError() == AL_INVALID_VALUE || (sourceType == TYPE_STREAM && !isPlaying())))
 	{
 		stop();
 		if (isLooping())
@@ -506,7 +506,7 @@ double Source::getDurationAtomic(void *vunit)
 {
 	Unit unit = *(Unit *) vunit;
 
-	switch (type)
+	switch (sourceType)
 	{
 		case TYPE_STATIC:
 		{
@@ -661,10 +661,10 @@ bool Source::isRelative() const
 
 void Source::setLooping(bool enable)
 {
-	if (type == TYPE_QUEUE)
+	if (sourceType == TYPE_QUEUE)
 		throw QueueLoopingException();
 
-	if (valid && type == TYPE_STATIC)
+	if (valid && sourceType == TYPE_STATIC)
 		alSourcei(source, AL_LOOPING, enable ? AL_TRUE : AL_FALSE);
 
 	looping = enable;
@@ -677,7 +677,7 @@ bool Source::isLooping() const
 
 bool Source::queue(void *data, size_t length, int dataSampleRate, int dataBitDepth, int dataChannels)
 {
-	if (type != TYPE_QUEUE)
+	if (sourceType != TYPE_QUEUE)
 		throw QueueTypeMismatchException();
 
 	if (dataSampleRate != sampleRate || dataBitDepth != bitDepth || dataChannels != channels )
@@ -721,7 +721,7 @@ bool Source::queueAtomic(void *data, ALsizei length)
 
 int Source::getFreeBufferCount() const
 {
-	switch (type) //why not :^)
+	switch (sourceType) //why not :^)
 	{
 		case TYPE_STATIC: 
 			return 0;
@@ -742,7 +742,7 @@ void Source::prepareAtomic()
 	// of the new one.
 	reset();
 
-	switch (type)
+	switch (sourceType)
 	{
 		case TYPE_STATIC:
 			alSourcei(source, AL_BUFFER, staticBuffer->getBuffer());
@@ -778,7 +778,7 @@ void Source::prepareAtomic()
 
 void Source::teardownAtomic()
 {
-	switch (type)
+	switch (sourceType)
 	{
 		case TYPE_STATIC:
 			break;
@@ -840,7 +840,7 @@ bool Source::playAtomic(ALuint source)
 
 	bool success = alGetError() == AL_NO_ERROR;
 
-	if (type == TYPE_STREAM)
+	if (sourceType == TYPE_STREAM)
 	{
 		valid = true; //isPlaying() needs source to be valid
 		if (!isPlaying())
@@ -857,7 +857,7 @@ bool Source::playAtomic(ALuint source)
 		valid = true; //stop() needs source to be valid
 		stop();
 	}
-	else if (type != TYPE_STREAM)
+	if (sourceType != TYPE_STREAM)
 		offsetSamples = offsetSeconds = 0;
 
 	//this is set to success state afterwards anyway, but setting it here
@@ -887,7 +887,7 @@ void Source::resumeAtomic()
 	{
 		alSourcePlay(source);
 
-		if (alGetError() == AL_INVALID_VALUE || (type == TYPE_STREAM && unusedBufferTop == MAX_BUFFERS - 1))
+		if (alGetError() == AL_INVALID_VALUE || (sourceType == TYPE_STREAM && unusedBufferTop == MAX_BUFFERS - 1))
 			stop();
 	}
 }
@@ -918,7 +918,7 @@ bool Source::playAtomic(const std::vector<love::audio::Source*> &sources, const
 		Source *source = (Source*) _source;
 		source->valid = source->valid || success;
 
-		if (success && source->type != TYPE_STREAM)
+		if (success && source->sourceType != TYPE_STREAM)
 			source->offsetSamples = source->offsetSeconds = 0;
 	}
 
@@ -979,7 +979,7 @@ void Source::reset()
 	alSourcef(source, AL_REFERENCE_DISTANCE, referenceDistance);
 	alSourcef(source, AL_ROLLOFF_FACTOR, rolloffFactor);
 	alSourcef(source, AL_MAX_DISTANCE, maxDistance);
-	alSourcei(source, AL_LOOPING, (type == TYPE_STATIC) && isLooping() ? AL_TRUE : AL_FALSE);
+	alSourcei(source, AL_LOOPING, (sourceType == TYPE_STATIC) && isLooping() ? AL_TRUE : AL_FALSE);
 	alSourcei(source, AL_SOURCE_RELATIVE, relative ? AL_TRUE : AL_FALSE);
 	alSourcei(source, AL_CONE_INNER_ANGLE, cone.innerAngle);
 	alSourcei(source, AL_CONE_OUTER_ANGLE, cone.outerAngle);

+ 12 - 12
src/modules/audio/wrap_Audio.cpp

@@ -46,31 +46,31 @@ int w_newSource(lua_State *L)
 {
 	Source::Type stype = Source::TYPE_STREAM;
 
-	if (!luax_istype(L, 1, SOUND_SOUND_DATA_ID) && !luax_istype(L, 1, SOUND_DECODER_ID))
+	if (!luax_istype(L, 1, love::sound::SoundData::type) && !luax_istype(L, 1, love::sound::Decoder::type))
 	{
 		const char *stypestr = luaL_checkstring(L, 2);
 		if (stypestr && !Source::getConstant(stypestr, stype))
 			return luaL_error(L, "Invalid source type: %s", stypestr);
 	}
 
-	if (lua_isstring(L, 1) || luax_istype(L, 1, FILESYSTEM_FILE_ID) || luax_istype(L, 1, FILESYSTEM_FILE_DATA_ID))
+	if (lua_isstring(L, 1) || luax_istype(L, 1, love::filesystem::File::type) || luax_istype(L, 1, love::filesystem::FileData::type))
 		luax_convobj(L, 1, "sound", "newDecoder");
 
-	if (stype == Source::TYPE_STATIC && luax_istype(L, 1, SOUND_DECODER_ID))
+	if (stype == Source::TYPE_STATIC && luax_istype(L, 1, love::sound::Decoder::type))
 		luax_convobj(L, 1, "sound", "newSoundData");
 
 	Source *t = nullptr;
 
 	luax_catchexcept(L, [&]() {
-		if (luax_istype(L, 1, SOUND_SOUND_DATA_ID))
-			t = instance()->newSource(luax_totype<love::sound::SoundData>(L, 1, SOUND_SOUND_DATA_ID));
-		else if (luax_istype(L, 1, SOUND_DECODER_ID))
-			t = instance()->newSource(luax_totype<love::sound::Decoder>(L, 1, SOUND_DECODER_ID));
+		if (luax_istype(L, 1, love::sound::SoundData::type))
+			t = instance()->newSource(luax_totype<love::sound::SoundData>(L, 1));
+		else if (luax_istype(L, 1, love::sound::Decoder::type))
+			t = instance()->newSource(luax_totype<love::sound::Decoder>(L, 1));
 	});
 
 	if (t != nullptr)
 	{
-		luax_pushtype(L, AUDIO_SOURCE_ID, t);
+		luax_pushtype(L, t);
 		t->release();
 		return 1;
 	}
@@ -88,7 +88,7 @@ int w_newQueueableSource(lua_State *L)
 
 	if (t != nullptr)
 	{
-		luax_pushtype(L, AUDIO_SOURCE_ID, t);
+		luax_pushtype(L, t);
 		t->release();
 		return 1;
 	}
@@ -150,7 +150,7 @@ int w_pause(lua_State *L)
 		lua_createtable(L, (int) sources.size(), 0);
 		for (int i = 0; i < (int) sources.size(); i++)
 		{
-			luax_pushtype(L, AUDIO_SOURCE_ID, sources[i]);
+			luax_pushtype(L, sources[i]);
 			lua_rawseti(L, -2, i+1);
 		}
 		return 1;
@@ -285,7 +285,7 @@ int w_getRecordingDevices(lua_State *L)
 
 	for (unsigned int i = 0; i < devices.size(); i++)
 	{
-		luax_pushtype(L, AUDIO_RECORDING_DEVICE_ID, devices[i]);
+		luax_pushtype(L, devices[i]);
 		lua_rawseti(L, -2, i + 1);
 	}
 
@@ -366,7 +366,7 @@ extern "C" int luaopen_love_audio(lua_State *L)
 	WrappedModule w;
 	w.module = instance;
 	w.name = "audio";
-	w.type = MODULE_ID;
+	w.type = &Module::type;
 	w.functions = functions;
 	w.types = types;
 

+ 4 - 4
src/modules/audio/wrap_RecordingDevice.cpp

@@ -29,7 +29,7 @@ namespace audio
 
 RecordingDevice *luax_checkrecordingdevice(lua_State *L, int idx)
 {
-	return luax_checktype<RecordingDevice>(L, idx, AUDIO_RECORDING_DEVICE_ID);
+	return luax_checktype<RecordingDevice>(L, idx);
 }
 
 int w_RecordingDevice_start(lua_State *L)
@@ -62,7 +62,7 @@ int w_RecordingDevice_stop(lua_State *L)
 
 	if (s != nullptr)
 	{
-		luax_pushtype(L, SOUND_SOUND_DATA_ID, s);
+		luax_pushtype(L, s);
 		s->release();
 	}
 	else
@@ -80,7 +80,7 @@ int w_RecordingDevice_getData(lua_State *L)
 
 	if (s != nullptr)
 	{
-		luax_pushtype(L, SOUND_SOUND_DATA_ID, s);
+		luax_pushtype(L, s);
 		s->release();
 	}
 	else
@@ -147,7 +147,7 @@ static const luaL_Reg w_RecordingDevice_functions[] =
 
 extern "C" int luaopen_recordingdevice(lua_State *L)
 {
-	int ret = luax_register_type(L, AUDIO_RECORDING_DEVICE_ID, "RecordingDevice", w_RecordingDevice_functions, nullptr);
+	int ret = luax_register_type(L, &RecordingDevice::type, w_RecordingDevice_functions, nullptr);
 	return ret;
 }
 

+ 5 - 5
src/modules/audio/wrap_Source.cpp

@@ -30,7 +30,7 @@ namespace audio
 
 Source *luax_checksource(lua_State *L, int idx)
 {
-	return luax_checktype<Source>(L, idx, AUDIO_SOURCE_ID);
+	return luax_checktype<Source>(L, idx);
 }
 
 int w_Source_clone(lua_State *L)
@@ -38,7 +38,7 @@ int w_Source_clone(lua_State *L)
 	Source *t = luax_checksource(L, 1);
 	Source *clone = nullptr;
 	luax_catchexcept(L, [&](){ clone = t->clone(); });
-	luax_pushtype(L, AUDIO_SOURCE_ID, clone);
+	luax_pushtype(L, clone);
 	clone->release();
 	return 1;
 }
@@ -342,9 +342,9 @@ int w_Source_queue(lua_State *L)
 	Source *t = luax_checksource(L, 1);
 	bool success;
 
-	if (luax_istype(L, 2, SOUND_SOUND_DATA_ID))
+	if (luax_istype(L, 2, love::sound::SoundData::type))
 	{
-		auto s = luax_totype<love::sound::SoundData>(L, 2, SOUND_SOUND_DATA_ID);
+		auto s = luax_totype<love::sound::SoundData>(L, 2);
 
 		int offset = 0;
 		size_t length = s->getSize();
@@ -450,7 +450,7 @@ static const luaL_Reg w_Source_functions[] =
 
 extern "C" int luaopen_source(lua_State *L)
 {
-	return luax_register_type(L, AUDIO_SOURCE_ID, "Source", w_Source_functions, nullptr);
+	return luax_register_type(L, &love::audio::Source::type, w_Source_functions, nullptr);
 }
 
 } // audio

+ 8 - 8
src/modules/event/sdl/Event.cpp

@@ -381,7 +381,7 @@ Message *Event::convert(const SDL_Event &e) const
 			{
 				Proxy proxy;
 				proxy.object = new love::filesystem::DroppedFile(e.drop.file);
-				proxy.type = FILESYSTEM_DROPPED_FILE_ID;
+				proxy.type = &love::filesystem::DroppedFile::type;
 				vargs.emplace_back(proxy.type, &proxy);
 				msg = new Message("filedropped", vargs);
 				proxy.object->release();
@@ -424,7 +424,7 @@ Message *Event::convertJoystickEvent(const SDL_Event &e) const
 	{
 	case SDL_JOYBUTTONDOWN:
 	case SDL_JOYBUTTONUP:
-		proxy.type = JOYSTICK_JOYSTICK_ID;
+		proxy.type = &love::joystick::Joystick::type;
 		proxy.object = joymodule->getJoystickFromID(e.jbutton.which);
 		if (!proxy.object)
 			break;
@@ -437,7 +437,7 @@ Message *Event::convertJoystickEvent(const SDL_Event &e) const
 		break;
 	case SDL_JOYAXISMOTION:
 		{
-			proxy.type = JOYSTICK_JOYSTICK_ID;
+			proxy.type = &love::joystick::Joystick::type;
 			proxy.object = joymodule->getJoystickFromID(e.jaxis.which);
 			if (!proxy.object)
 				break;
@@ -453,7 +453,7 @@ Message *Event::convertJoystickEvent(const SDL_Event &e) const
 		if (!joystick::sdl::Joystick::getConstant(e.jhat.value, hat) || !joystick::Joystick::getConstant(hat, txt))
 			break;
 
-		proxy.type = JOYSTICK_JOYSTICK_ID;
+		proxy.type = &love::joystick::Joystick::type;
 		proxy.object = joymodule->getJoystickFromID(e.jhat.which);
 		if (!proxy.object)
 			break;
@@ -471,7 +471,7 @@ Message *Event::convertJoystickEvent(const SDL_Event &e) const
 		if (!joystick::Joystick::getConstant(padbutton, txt))
 			break;
 
-		proxy.type = JOYSTICK_JOYSTICK_ID;
+		proxy.type = &love::joystick::Joystick::type;
 		proxy.object = joymodule->getJoystickFromID(e.cbutton.which);
 		if (!proxy.object)
 			break;
@@ -487,7 +487,7 @@ Message *Event::convertJoystickEvent(const SDL_Event &e) const
 			if (!joystick::Joystick::getConstant(padaxis, txt))
 				break;
 
-			proxy.type = JOYSTICK_JOYSTICK_ID;
+			proxy.type = &love::joystick::Joystick::type;
 			proxy.object = joymodule->getJoystickFromID(e.caxis.which);
 			if (!proxy.object)
 				break;
@@ -503,7 +503,7 @@ Message *Event::convertJoystickEvent(const SDL_Event &e) const
 	case SDL_JOYDEVICEADDED:
 		// jdevice.which is the joystick device index.
 		proxy.object = joymodule->addJoystick(e.jdevice.which);
-		proxy.type = JOYSTICK_JOYSTICK_ID;
+		proxy.type = &love::joystick::Joystick::type;
 		if (proxy.object)
 		{
 			vargs.emplace_back(proxy.type, (void *) &proxy);
@@ -513,7 +513,7 @@ Message *Event::convertJoystickEvent(const SDL_Event &e) const
 	case SDL_JOYDEVICEREMOVED:
 		// jdevice.which is the joystick instance ID now.
 		proxy.object = joymodule->getJoystickFromID(e.jdevice.which);
-		proxy.type = JOYSTICK_JOYSTICK_ID;
+		proxy.type = &love::joystick::Joystick::type;
 		if (proxy.object)
 		{
 			joymodule->removeJoystick((joystick::Joystick *) proxy.object);

+ 1 - 1
src/modules/event/wrap_Event.cpp

@@ -128,7 +128,7 @@ extern "C" int luaopen_love_event(lua_State *L)
 	WrappedModule w;
 	w.module = instance;
 	w.name = "event";
-	w.type = MODULE_ID;
+	w.type = &Module::type;
 	w.functions = functions;
 	w.types = nullptr;
 

+ 2 - 0
src/modules/filesystem/DroppedFile.cpp

@@ -37,6 +37,8 @@ namespace love
 namespace filesystem
 {
 
+love::Type DroppedFile::type("DroppedFile", &File::type);
+
 DroppedFile::DroppedFile(const std::string &filename)
 	: filename(filename)
 	, file(nullptr)

+ 2 - 0
src/modules/filesystem/DroppedFile.h

@@ -41,6 +41,8 @@ class DroppedFile : public File
 {
 public:
 
+	static love::Type type;
+
 	DroppedFile(const std::string &filename);
 	virtual ~DroppedFile();
 

+ 2 - 0
src/modules/filesystem/File.cpp

@@ -25,6 +25,8 @@ namespace love
 namespace filesystem
 {
 
+love::Type File::type("File", &Object::type);
+
 File::~File()
 {
 }

+ 2 - 0
src/modules/filesystem/File.h

@@ -44,6 +44,8 @@ class File : public Object
 {
 public:
 
+	static love::Type type;
+
 	/**
 	 * File open mode.
 	 **/

+ 2 - 0
src/modules/filesystem/FileData.cpp

@@ -29,6 +29,8 @@ namespace love
 namespace filesystem
 {
 
+love::Type FileData::type("FileData", &Data::type);
+
 FileData::FileData(uint64 size, const std::string &filename)
 	: data(nullptr)
 	, size((size_t) size)

+ 2 - 0
src/modules/filesystem/FileData.h

@@ -37,6 +37,8 @@ class FileData : public Data
 {
 public:
 
+	static love::Type type;
+
 	FileData(uint64 size, const std::string &filename);
 
 	virtual ~FileData();

+ 2 - 0
src/modules/filesystem/Filesystem.cpp

@@ -42,6 +42,8 @@ namespace love
 namespace filesystem
 {
 
+love::Type Filesystem::type("filesystem", &Module::type);
+
 Filesystem::Filesystem()
 {
 }

+ 2 - 0
src/modules/filesystem/Filesystem.h

@@ -61,6 +61,8 @@ class Filesystem : public Module
 {
 public:
 
+	static love::Type type;
+
 	Filesystem();
 	virtual ~Filesystem();
 

+ 2 - 2
src/modules/filesystem/wrap_DroppedFile.cpp

@@ -28,12 +28,12 @@ namespace filesystem
 
 DroppedFile *luax_checkdroppedfile(lua_State *L, int idx)
 {
-	return luax_checktype<DroppedFile>(L, idx, FILESYSTEM_DROPPED_FILE_ID);
+	return luax_checktype<DroppedFile>(L, idx);
 }
 
 extern "C" int luaopen_droppedfile(lua_State *L)
 {
-	return luax_register_type(L, FILESYSTEM_DROPPED_FILE_ID, "DroppedFile", w_File_functions, nullptr);
+	return luax_register_type(L, &DroppedFile::type, w_File_functions, nullptr);
 }
 
 } // filesystem

+ 5 - 5
src/modules/filesystem/wrap_File.cpp

@@ -43,7 +43,7 @@ int luax_ioError(lua_State *L, const char *fmt, ...)
 
 File *luax_checkfile(lua_State *L, int idx)
 {
-	return luax_checktype<File>(L, idx, FILESYSTEM_FILE_ID);
+	return luax_checktype<File>(L, idx);
 }
 
 int w_File_getSize(lua_State *L)
@@ -148,11 +148,11 @@ int w_File_write(lua_State *L)
 			return luax_ioError(L, "%s", e.what());
 		}
 	}
-	else if (luax_istype(L, 2, DATA_ID))
+	else if (luax_istype(L, 2, love::Data::type))
 	{
 		try
 		{
-			love::Data *data = luax_totype<love::Data>(L, 2, DATA_ID);
+			love::Data *data = luax_totype<love::Data>(L, 2);
 			result = file->write(data, luaL_optinteger(L, 3, data->getSize()));
 		}
 		catch (love::Exception &e)
@@ -227,7 +227,7 @@ int w_File_lines_i(lua_State *L)
 	int linesize = 0;
 	bool newline = false;
 
-	File *file = luax_checktype<File>(L, lua_upvalueindex(1), FILESYSTEM_FILE_ID);
+	File *file = luax_checktype<File>(L, lua_upvalueindex(1));
 
 	// Only accept read mode at this point.
 	if (file->getMode() != File::MODE_READ)
@@ -435,7 +435,7 @@ const luaL_Reg w_File_functions[] =
 
 extern "C" int luaopen_file(lua_State *L)
 {
-	return luax_register_type(L, FILESYSTEM_FILE_ID, "File", w_File_functions, nullptr);
+	return luax_register_type(L, &File::type, w_File_functions, nullptr);
 }
 
 } // filesystem

+ 2 - 2
src/modules/filesystem/wrap_FileData.cpp

@@ -29,7 +29,7 @@ namespace filesystem
 
 FileData *luax_checkfiledata(lua_State *L, int idx)
 {
-	return luax_checktype<FileData>(L, idx, FILESYSTEM_FILE_DATA_ID);
+	return luax_checktype<FileData>(L, idx);
 }
 
 int w_FileData_getFilename(lua_State *L)
@@ -56,7 +56,7 @@ static const luaL_Reg w_FileData_functions[] =
 
 extern "C" int luaopen_filedata(lua_State *L)
 {
-	return luax_register_type(L, FILESYSTEM_FILE_DATA_ID, "FileData", w_Data_functions, w_FileData_functions, nullptr);
+	return luax_register_type(L, &FileData::type, w_Data_functions, w_FileData_functions, nullptr);
 }
 
 } // filesystem

+ 13 - 13
src/modules/filesystem/wrap_Filesystem.cpp

@@ -113,9 +113,9 @@ int w_mount(lua_State *L)
 {
 	std::string archive;
 
-	if (luax_istype(L, 1, FILESYSTEM_DROPPED_FILE_ID))
+	if (luax_istype(L, 1, DroppedFile::type))
 	{
-		DroppedFile *file = luax_totype<DroppedFile>(L, 1, FILESYSTEM_DROPPED_FILE_ID);
+		DroppedFile *file = luax_totype<DroppedFile>(L, 1);
 		archive = file->getFilename();
 	}
 	else
@@ -166,7 +166,7 @@ int w_newFile(lua_State *L)
 		}
 	}
 
-	luax_pushtype(L, FILESYSTEM_FILE_ID, t);
+	luax_pushtype(L, t);
 	t->release();
 	return 1;
 }
@@ -190,12 +190,12 @@ FileData *luax_getfiledata(lua_State *L, int idx)
 	FileData *data = nullptr;
 	File *file = nullptr;
 
-	if (lua_isstring(L, idx) || luax_istype(L, idx, FILESYSTEM_FILE_ID))
+	if (lua_isstring(L, idx) || luax_istype(L, idx, File::type))
 	{
 		file = luax_getfile(L, idx);
 		file->retain();
 	}
-	else if (luax_istype(L, idx, FILESYSTEM_FILE_DATA_ID))
+	else if (luax_istype(L, idx, FileData::type))
 	{
 		data = luax_checkfiledata(L, idx);
 		data->retain();
@@ -220,7 +220,7 @@ FileData *luax_getfiledata(lua_State *L, int idx)
 
 bool luax_cangetfiledata(lua_State *L, int idx)
 {
-	return lua_isstring(L, idx) || luax_istype(L, idx, FILESYSTEM_FILE_ID) || luax_istype(L, idx, FILESYSTEM_FILE_DATA_ID);
+	return lua_isstring(L, idx) || luax_istype(L, idx, File::type) || luax_istype(L, idx, FileData::type);
 }
 
 int w_newFileData(lua_State *L)
@@ -233,7 +233,7 @@ int w_newFileData(lua_State *L)
 			luax_convobj(L, 1, "filesystem", "newFile");
 
 		// Get FileData from the File.
-		if (luax_istype(L, 1, FILESYSTEM_FILE_ID))
+		if (luax_istype(L, 1, File::type))
 		{
 			File *file = luax_checkfile(L, 1);
 
@@ -246,7 +246,7 @@ int w_newFileData(lua_State *L)
 			{
 				return luax_ioError(L, "%s", e.what());
 			}
-			luax_pushtype(L, FILESYSTEM_FILE_DATA_ID, data);
+			luax_pushtype(L, data);
 			return 1;
 		}
 		else
@@ -260,7 +260,7 @@ int w_newFileData(lua_State *L)
 	FileData *t = nullptr;
 	luax_catchexcept(L, [&](){ t = instance()->newFileData(str, length, filename); });
 
-	luax_pushtype(L, FILESYSTEM_FILE_DATA_ID, t);
+	luax_pushtype(L, t);
 	t->release();
 	return 1;
 }
@@ -398,9 +398,9 @@ static int w_write_or_append(lua_State *L, File::Mode mode)
 	const char *input = 0;
 	size_t len = 0;
 
-	if (luax_istype(L, 2, DATA_ID))
+	if (luax_istype(L, 2, love::Data::type))
 	{
-		love::Data *data = luax_totype<love::Data>(L, 2, DATA_ID);
+		love::Data *data = luax_totype<love::Data>(L, 2);
 		input = (const char *) data->getData();
 		len = data->getSize();
 	}
@@ -474,7 +474,7 @@ int w_lines(lua_State *L)
 			return luaL_error(L, "Could not open file.");
 		}
 
-		luax_pushtype(L, FILESYSTEM_FILE_ID, file);
+		luax_pushtype(L, file);
 		file->release();
 	}
 	else
@@ -810,7 +810,7 @@ extern "C" int luaopen_love_filesystem(lua_State *L)
 	WrappedModule w;
 	w.module = instance;
 	w.name = "filesystem";
-	w.type = MODULE_FILESYSTEM_ID;
+	w.type = &Filesystem::type;
 	w.functions = functions;
 	w.types = types;
 

+ 2 - 0
src/modules/font/GlyphData.cpp

@@ -33,6 +33,8 @@ namespace love
 namespace font
 {
 
+love::Type GlyphData::type("GlyphData", &Data::type);
+
 GlyphData::GlyphData(uint32 glyph, GlyphMetrics glyphMetrics, GlyphData::Format f)
 	: glyph(glyph)
 	, metrics(glyphMetrics)

+ 2 - 0
src/modules/font/GlyphData.h

@@ -55,6 +55,8 @@ class GlyphData : public Data
 {
 public:
 
+	static love::Type type;
+
 	enum Format
 	{
 		FORMAT_LUMINANCE_ALPHA,

+ 2 - 0
src/modules/font/Rasterizer.cpp

@@ -29,6 +29,8 @@ namespace love
 namespace font
 {
 
+love::Type Rasterizer::type("Rasterizer", &Object::type);
+
 Rasterizer::~Rasterizer()
 {
 }

+ 2 - 0
src/modules/font/Rasterizer.h

@@ -49,6 +49,8 @@ class Rasterizer : public Object
 {
 public:
 
+	static love::Type type;
+
 	virtual ~Rasterizer();
 
 	/**

+ 11 - 11
src/modules/font/wrap_Font.cpp

@@ -53,7 +53,7 @@ int w_newRasterizer(lua_State *L)
 			[&](bool) { d->release(); }
 		);
 
-		luax_pushtype(L, FONT_RASTERIZER_ID, t);
+		luax_pushtype(L, t);
 		t->release();
 		return 1;
 	}
@@ -84,7 +84,7 @@ int w_newTrueTypeRasterizer(lua_State *L)
 	{
 		love::Data *d = nullptr;
 
-		if (luax_istype(L, 1, DATA_ID))
+		if (luax_istype(L, 1, love::Data::type))
 		{
 			d = luax_checkdata(L, 1);
 			d->retain();
@@ -104,14 +104,14 @@ int w_newTrueTypeRasterizer(lua_State *L)
 		);
 	}
 
-	luax_pushtype(L, FONT_RASTERIZER_ID, t);
+	luax_pushtype(L, t);
 	t->release();
 	return 1;
 }
 
 static void convimagedata(lua_State *L, int idx)
 {
-	if (lua_type(L, 1) == LUA_TSTRING || luax_istype(L, idx, FILESYSTEM_FILE_ID) || luax_istype(L, idx, FILESYSTEM_FILE_DATA_ID))
+	if (lua_type(L, 1) == LUA_TSTRING || luax_istype(L, idx, love::filesystem::File::type) || luax_istype(L, idx, love::filesystem::FileData::type))
 		luax_convobj(L, idx, "image", "newImageData");
 }
 
@@ -129,7 +129,7 @@ int w_newBMFontRasterizer(lua_State *L)
 			lua_rawgeti(L, 2, i);
 
 			convimagedata(L, -1);
-			image::ImageData *id = luax_checktype<image::ImageData>(L, -1, IMAGE_IMAGE_DATA_ID);
+			image::ImageData *id = luax_checktype<image::ImageData>(L, -1);
 			images.push_back(id);
 			id->retain();
 
@@ -141,7 +141,7 @@ int w_newBMFontRasterizer(lua_State *L)
 		for (int i = 2; i <= lua_gettop(L); i++)
 		{
 			convimagedata(L, i);
-			image::ImageData *id = luax_checktype<image::ImageData>(L, i, IMAGE_IMAGE_DATA_ID);
+			image::ImageData *id = luax_checktype<image::ImageData>(L, i);
 			images.push_back(id);
 			id->retain();
 		}
@@ -152,7 +152,7 @@ int w_newBMFontRasterizer(lua_State *L)
 		[&](bool) { d->release(); for (auto id : images) id->release(); }
 	);
 
-	luax_pushtype(L, FONT_RASTERIZER_ID, t);
+	luax_pushtype(L, t);
 	t->release();
 	return 1;
 }
@@ -163,13 +163,13 @@ int w_newImageRasterizer(lua_State *L)
 
 	convimagedata(L, 1);
 
-	image::ImageData *d = luax_checktype<image::ImageData>(L, 1, IMAGE_IMAGE_DATA_ID);
+	image::ImageData *d = luax_checktype<image::ImageData>(L, 1);
 	std::string glyphs = luax_checkstring(L, 2);
 	int extraspacing = (int) luaL_optnumber(L, 3, 0);
 
 	luax_catchexcept(L, [&](){ t = instance()->newImageRasterizer(d, glyphs, extraspacing); });
 
-	luax_pushtype(L, FONT_RASTERIZER_ID, t);
+	luax_pushtype(L, t);
 	t->release();
 	return 1;
 }
@@ -191,7 +191,7 @@ int w_newGlyphData(lua_State *L)
 		t = instance()->newGlyphData(r, g);
 	}
 
-	luax_pushtype(L, FONT_GLYPH_DATA_ID, t);
+	luax_pushtype(L, t);
 	t->release();
 	return 1;
 }
@@ -227,7 +227,7 @@ extern "C" int luaopen_love_font(lua_State *L)
 	WrappedModule w;
 	w.module = instance;
 	w.name = "font";
-	w.type = MODULE_ID;
+	w.type = &Module::type;
 	w.functions = functions;
 	w.types = types;
 

+ 2 - 2
src/modules/font/wrap_GlyphData.cpp

@@ -27,7 +27,7 @@ namespace font
 
 GlyphData *luax_checkglyphdata(lua_State *L, int idx)
 {
-	return luax_checktype<GlyphData>(L, idx, FONT_GLYPH_DATA_ID);
+	return luax_checktype<GlyphData>(L, idx);
 }
 
 int w_GlyphData_getWidth(lua_State *L)
@@ -131,7 +131,7 @@ const luaL_Reg w_GlyphData_functions[] =
 
 extern "C" int luaopen_glyphdata(lua_State *L)
 {
-	return luax_register_type(L, FONT_GLYPH_DATA_ID, "GlyphData", w_Data_functions, w_GlyphData_functions, nullptr);
+	return luax_register_type(L, &GlyphData::type, w_Data_functions, w_GlyphData_functions, nullptr);
 }
 
 } // font

+ 3 - 3
src/modules/font/wrap_Rasterizer.cpp

@@ -29,7 +29,7 @@ namespace font
 
 Rasterizer *luax_checkrasterizer(lua_State *L, int idx)
 {
-	return luax_checktype<Rasterizer>(L, idx, FONT_RASTERIZER_ID);
+	return luax_checktype<Rasterizer>(L, idx);
 }
 
 int w_Rasterizer_getHeight(lua_State *L)
@@ -86,7 +86,7 @@ int w_Rasterizer_getGlyphData(lua_State *L)
 		}
 	});
 
-	luax_pushtype(L, FONT_GLYPH_DATA_ID, g);
+	luax_pushtype(L, g);
 	g->release();
 	return 1;
 }
@@ -139,7 +139,7 @@ const luaL_Reg w_Rasterizer_functions[] =
 
 extern "C" int luaopen_rasterizer(lua_State *L)
 {
-	return luax_register_type(L, FONT_RASTERIZER_ID, "Rasterizer", w_Rasterizer_functions, nullptr);
+	return luax_register_type(L, &Rasterizer::type, w_Rasterizer_functions, nullptr);
 }
 
 } // font

+ 32 - 0
src/modules/graphics/Drawable.cpp

@@ -0,0 +1,32 @@
+/**
+ * Copyright (c) 2006-2016 LOVE Development Team
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.  In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ *    claim that you wrote the original software. If you use this software
+ *    in a product, an acknowledgment in the product documentation would be
+ *    appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ *    misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ **/
+
+// LOVE
+#include "Drawable.h"
+
+namespace love
+{
+namespace graphics
+{
+
+love::Type Drawable::type("Drawable", &Object::type);
+
+} // graphics
+} // love

+ 2 - 0
src/modules/graphics/Drawable.h

@@ -38,6 +38,8 @@ class Drawable : public Object
 {
 public:
 
+	static love::Type type;
+
 	/**
 	 * Destructor.
 	 **/

+ 2 - 0
src/modules/graphics/Graphics.cpp

@@ -58,6 +58,8 @@ void unGammaCorrectColor(Colorf &c)
 	}
 }
 
+love::Type Graphics::type("graphics", &Module::type);
+
 Graphics::~Graphics()
 {
 }

+ 2 - 0
src/modules/graphics/Graphics.h

@@ -73,6 +73,8 @@ class Graphics : public Module
 {
 public:
 
+	static love::Type type;
+
 	enum DrawMode
 	{
 		DRAW_LINE,

+ 2 - 0
src/modules/graphics/ParticleSystem.cpp

@@ -50,6 +50,8 @@ float calculate_variation(float inner, float outer, float var)
 
 } // anonymous namespace
 
+love::Type ParticleSystem::type("ParticleSystem", &Drawable::type);
+
 ParticleSystem::ParticleSystem(Texture *texture, uint32 size)
 	: pMem(nullptr)
 	, pFree(nullptr)

+ 3 - 0
src/modules/graphics/ParticleSystem.h

@@ -45,6 +45,9 @@ namespace graphics
 class ParticleSystem : public Drawable
 {
 public:
+
+	static love::Type type;
+
 	/**
 	 * Type of distribution new particles are drawn from: None, uniform, normal, ellipse.
 	 */

+ 2 - 0
src/modules/graphics/Quad.cpp

@@ -29,6 +29,8 @@ namespace love
 namespace graphics
 {
 
+love::Type Quad::type("Quad", &Object::type);
+
 Quad::Quad(const Quad::Viewport &v, double sw, double sh)
 	: sw(sw)
 	, sh(sh)

+ 2 - 0
src/modules/graphics/Quad.h

@@ -34,6 +34,8 @@ class Quad : public Object
 {
 public:
 
+	static love::Type type;
+
 	struct Viewport
 	{
 		double x, y;

+ 1 - 0
src/modules/graphics/Texture.cpp

@@ -25,6 +25,7 @@ namespace love
 namespace graphics
 {
 
+love::Type Texture::type("Texture", &Drawable::type);
 Texture::Filter Texture::defaultFilter;
 
 Texture::Texture()

+ 2 - 0
src/modules/graphics/Texture.h

@@ -41,6 +41,8 @@ class Texture : public Drawable
 {
 public:
 
+	static love::Type type;
+
 	enum WrapMode
 	{
 		WRAP_CLAMP,

+ 1 - 0
src/modules/graphics/opengl/Canvas.cpp

@@ -99,6 +99,7 @@ static bool createMSAABuffer(int width, int height, int &samples, PixelFormat pi
 	return status == GL_FRAMEBUFFER_COMPLETE && samples > 1;
 }
 
+love::Type Canvas::type("Canvas", &Texture::type);
 int Canvas::canvasCount = 0;
 
 Canvas::Canvas(int width, int height, PixelFormat format, int msaa)

+ 2 - 0
src/modules/graphics/opengl/Canvas.h

@@ -43,6 +43,8 @@ class Canvas : public Texture, public Volatile
 {
 public:
 
+	static love::Type type;
+
 	Canvas(int width, int height, PixelFormat format = PIXELFORMAT_NORMAL, int msaa = 0);
 	virtual ~Canvas();
 

+ 7 - 6
src/modules/graphics/opengl/Font.cpp

@@ -44,6 +44,7 @@ static inline uint16 normToUint16(double n)
 	return (uint16) (n * LOVE_UINT16_MAX);
 }
 
+love::Type Font::type("Font", &Object::type);
 int Font::fontCount = 0;
 
 Font::Font(love::font::Rasterizer *r, const Texture::Filter &filter)
@@ -77,7 +78,7 @@ Font::Font(love::font::Rasterizer *r, const Texture::Filter &filter)
 	}
 
 	love::font::GlyphData *gd = r->getGlyphData(32); // Space character.
-	type = (gd->getFormat() == font::GlyphData::FORMAT_LUMINANCE_ALPHA) ? FONT_TRUETYPE : FONT_IMAGE;
+	fontType = (gd->getFormat() == font::GlyphData::FORMAT_LUMINANCE_ALPHA) ? FONT_TRUETYPE : FONT_IMAGE;
 	gd->release();
 
 	if (!r->hasGlyph(9)) // No tab character in the Rasterizer.
@@ -142,7 +143,7 @@ void Font::createTexture()
 {
 	OpenGL::TempDebugGroup debuggroup("Font create texture");
 
-	size_t bpp = type == FONT_TRUETYPE ? 2 : 4;
+	size_t bpp = fontType == FONT_TRUETYPE ? 2 : 4;
 
 	size_t prevmemsize = textureMemorySize;
 	if (prevmemsize > 0)
@@ -177,7 +178,7 @@ void Font::createTexture()
 	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
 
 	GLenum internalformat = GL_RGBA;
-	GLenum format = getTextureFormat(type, &internalformat);
+	GLenum format = getTextureFormat(fontType, &internalformat);
 
 	// Initialize the texture with transparent black.
 	std::vector<GLubyte> emptydata(size.width * size.height * bpp, 0);
@@ -285,7 +286,7 @@ const Font::Glyph &Font::addGlyph(uint32 glyph)
 	// don't waste space for empty glyphs. also fixes a divide by zero bug with ATI drivers
 	if (w > 0 && h > 0)
 	{
-		GLenum format = getTextureFormat(type);
+		GLenum format = getTextureFormat(fontType);
 		g.texture = textures.back();
 
 		gl.bindTextureToUnit(g.texture, 0, false);
@@ -1021,7 +1022,7 @@ int Font::getDescent() const
 float Font::getBaseline() const
 {
 	// 1.25 is magic line height for true type fonts
-	return (type == FONT_TRUETYPE) ? floorf(getHeight() / 1.25f + 0.5f) : 0.0f;
+	return (fontType == FONT_TRUETYPE) ? floorf(getHeight() / 1.25f + 0.5f) : 0.0f;
 }
 
 bool Font::hasGlyph(uint32 glyph) const
@@ -1065,7 +1066,7 @@ void Font::setFallbacks(const std::vector<Font *> &fallbacks)
 {
 	for (const Font *f : fallbacks)
 	{
-		if (f->type != this->type)
+		if (f->fontType != this->fontType)
 			throw love::Exception("Font fallbacks must be of the same font type.");
 	}
 

+ 3 - 1
src/modules/graphics/opengl/Font.h

@@ -50,6 +50,8 @@ class Font : public Object, public Volatile
 {
 public:
 
+	static love::Type type;
+
 	typedef std::vector<uint32> Codepoints;
 
 	enum AlignMode
@@ -235,7 +237,7 @@ private:
 	// map of left/right glyph pairs to horizontal kerning.
 	std::unordered_map<uint64, float> kerning;
 
-	FontType type;
+	FontType fontType;
 	Texture::Filter filter;
 
 	int textureX, textureY;

+ 2 - 0
src/modules/graphics/opengl/Image.cpp

@@ -43,6 +43,8 @@ namespace graphics
 namespace opengl
 {
 
+love::Type Image::type("Image", &Texture::type);
+
 int Image::imageCount = 0;
 
 float Image::maxMipmapSharpness = 0.0f;

+ 2 - 0
src/modules/graphics/opengl/Image.h

@@ -52,6 +52,8 @@ class Image : public Texture, public Volatile
 {
 public:
 
+	static love::Type type;
+
 	enum FlagType
 	{
 		FLAG_TYPE_MIPMAPS,

+ 2 - 0
src/modules/graphics/opengl/Mesh.cpp

@@ -58,6 +58,8 @@ static std::vector<Mesh::AttribFormat> getDefaultVertexFormat()
 	return vertexformat;
 }
 
+love::Type Mesh::type("Mesh", &Drawable::type);
+
 Mesh::Mesh(const std::vector<AttribFormat> &vertexformat, const void *data, size_t datasize, DrawMode drawmode, Usage usage)
 	: vertexFormat(vertexformat)
 	, vbo(nullptr)

+ 2 - 0
src/modules/graphics/opengl/Mesh.h

@@ -50,6 +50,8 @@ class Mesh : public Drawable
 {
 public:
 
+	static love::Type type;
+
 	// The expected usage pattern of the Mesh's vertex data.
 	enum Usage
 	{

+ 1 - 0
src/modules/graphics/opengl/Shader.cpp

@@ -69,6 +69,7 @@ namespace
 } // anonymous namespace
 
 
+love::Type Shader::type("Shader", &Object::type);
 Shader *Shader::current = nullptr;
 Shader *Shader::defaultShader = nullptr;
 Shader *Shader::defaultVideoShader = nullptr;

+ 2 - 0
src/modules/graphics/opengl/Shader.h

@@ -46,6 +46,8 @@ class Shader : public Object, public Volatile
 {
 public:
 
+	static love::Type type;
+
 	enum ShaderStage
 	{
 		STAGE_VERTEX,

+ 2 - 0
src/modules/graphics/opengl/SpriteBatch.cpp

@@ -41,6 +41,8 @@ namespace graphics
 namespace opengl
 {
 
+love::Type SpriteBatch::type("SpriteBatch", &Drawable::type);
+
 SpriteBatch::SpriteBatch(Texture *texture, int size, Mesh::Usage usage)
 	: texture(texture)
 	, size(size)

+ 2 - 0
src/modules/graphics/opengl/SpriteBatch.h

@@ -52,6 +52,8 @@ class SpriteBatch : public Drawable
 {
 public:
 
+	static love::Type type;
+
 	SpriteBatch(Texture *texture, int size, Mesh::Usage usage);
 	virtual ~SpriteBatch();
 

+ 2 - 0
src/modules/graphics/opengl/Text.cpp

@@ -30,6 +30,8 @@ namespace graphics
 namespace opengl
 {
 
+love::Type Text::type("Text", &Drawable::type);
+
 Text::Text(Font *font, const std::vector<Font::ColoredString> &text)
 	: font(font)
 	, vbo(nullptr)

+ 2 - 0
src/modules/graphics/opengl/Text.h

@@ -38,6 +38,8 @@ class Text : public Drawable
 {
 public:
 
+	static love::Type type;
+
 	Text(Font *font, const std::vector<Font::ColoredString> &text = {});
 	virtual ~Text();
 

+ 2 - 0
src/modules/graphics/opengl/Video.cpp

@@ -30,6 +30,8 @@ namespace graphics
 namespace opengl
 {
 
+love::Type Video::type("Video", &Drawable::type);
+
 Video::Video(love::video::VideoStream *stream)
 	: stream(stream)
 	, filter(Texture::getDefaultFilter())

+ 2 - 0
src/modules/graphics/opengl/Video.h

@@ -40,6 +40,8 @@ class Video : public Drawable, public Volatile
 {
 public:
 
+	static love::Type type;
+
 	Video(love::video::VideoStream *stream);
 	~Video();
 

+ 2 - 2
src/modules/graphics/opengl/wrap_Canvas.cpp

@@ -30,7 +30,7 @@ namespace opengl
 
 Canvas *luax_checkcanvas(lua_State *L, int idx)
 {
-	return luax_checktype<Canvas>(L, idx, GRAPHICS_CANVAS_ID);
+	return luax_checktype<Canvas>(L, idx);
 }
 
 int w_Canvas_getFormat(lua_State *L)
@@ -61,7 +61,7 @@ static const luaL_Reg w_Canvas_functions[] =
 
 extern "C" int luaopen_canvas(lua_State *L)
 {
-	return luax_register_type(L, GRAPHICS_CANVAS_ID, "Canvas", w_Texture_functions, w_Canvas_functions, nullptr);
+	return luax_register_type(L, &Canvas::type, w_Texture_functions, w_Canvas_functions, nullptr);
 }
 
 } // opengl

+ 2 - 2
src/modules/graphics/opengl/wrap_Font.cpp

@@ -35,7 +35,7 @@ namespace opengl
 
 Font *luax_checkfont(lua_State *L, int idx)
 {
-	return luax_checktype<Font>(L, idx, GRAPHICS_FONT_ID);
+	return luax_checktype<Font>(L, idx);
 }
 
 int w_Font_getHeight(lua_State *L)
@@ -207,7 +207,7 @@ static const luaL_Reg w_Font_functions[] =
 
 extern "C" int luaopen_font(lua_State *L)
 {
-	return luax_register_type(L, GRAPHICS_FONT_ID, "Font", w_Font_functions, nullptr);
+	return luax_register_type(L, &Font::type, w_Font_functions, nullptr);
 }
 
 } // opengl

+ 46 - 46
src/modules/graphics/opengl/wrap_Graphics.cpp

@@ -153,7 +153,7 @@ static int w__beginPass(lua_State *L)
 
 		luax_catchexcept(L, [&]() { instance()->beginPass(PassInfo::BEGIN_CLEAR, c); });
 	}
-	else if (luax_istype(L, 1, GRAPHICS_CANVAS_ID))
+	else if (luax_istype(L, 1, Canvas::type))
 	{
 		PassInfo::ColorAttachment attachment;
 		attachment.canvas = luax_checkcanvas(L, 1);
@@ -257,7 +257,7 @@ static void screenshotCallback(love::image::ImageData *i, Reference *ref, void *
 		lua_State *L = (lua_State *) gd;
 		ref->push(L);
 		delete ref;
-		luax_pushtype(L, IMAGE_IMAGE_DATA_ID, i);
+		luax_pushtype(L, i);
 		lua_call(L, 1, 0);
 	}
 	else
@@ -349,7 +349,7 @@ int w_getPassCanvases(lua_State *L)
 	const PassInfo &info = instance()->getActivePass();
 
 	for (const auto &attachment : info.colorAttachments)
-		luax_pushtype(L, GRAPHICS_CANVAS_ID, attachment.canvas);
+		luax_pushtype(L, attachment.canvas);
 
 	return info.colorAttachmentCount;
 }
@@ -513,7 +513,7 @@ int w_newImage(lua_State *L)
 	bool releasedata = false;
 
 	// Convert to ImageData / CompressedImageData, if necessary.
-	if (lua_isstring(L, 1) || luax_istype(L, 1, FILESYSTEM_FILE_ID) || luax_istype(L, 1, FILESYSTEM_FILE_DATA_ID))
+	if (lua_isstring(L, 1) || luax_istype(L, 1, love::filesystem::File::type) || luax_istype(L, 1, love::filesystem::FileData::type))
 	{
 		auto imagemodule = Module::getInstance<love::image::Image>(Module::M_IMAGE);
 		if (imagemodule == nullptr)
@@ -539,7 +539,7 @@ int w_newImage(lua_State *L)
 		// Lua's GC won't release the image data, so we should do it ourselves.
 		releasedata = true;
 	}
-	else if (luax_istype(L, 1, IMAGE_COMPRESSED_IMAGE_DATA_ID))
+	else if (luax_istype(L, 1, love::image::CompressedImageData::type))
 		cdata.push_back(love::image::luax_checkcompressedimagedata(L, 1));
 	else
 		data.push_back(love::image::luax_checkimagedata(L, 1));
@@ -558,14 +558,14 @@ int w_newImage(lua_State *L)
 
 				if (!data.empty())
 				{
-					if (!luax_istype(L, -1, IMAGE_IMAGE_DATA_ID))
+					if (!luax_istype(L, -1, love::image::ImageData::type))
 						luax_convobj(L, -1, "image", "newImageData");
 
 					data.push_back(love::image::luax_checkimagedata(L, -1));
 				}
 				else if (!cdata.empty())
 				{
-					if (!luax_istype(L, -1, IMAGE_COMPRESSED_IMAGE_DATA_ID))
+					if (!luax_istype(L, -1, love::image::CompressedImageData::type))
 						luax_convobj(L, -1, "image", "newCompressedData");
 
 					cdata.push_back(love::image::luax_checkcompressedimagedata(L, -1));
@@ -602,7 +602,7 @@ int w_newImage(lua_State *L)
 		return luaL_error(L, "Could not load image.");
 
 	// Push the type.
-	luax_pushtype(L, GRAPHICS_IMAGE_ID, image);
+	luax_pushtype(L, image);
 	image->release();
 	return 1;
 }
@@ -621,7 +621,7 @@ int w_newQuad(lua_State *L)
 	double sh = luaL_checknumber(L, 6);
 
 	Quad *quad = instance()->newQuad(v, sw, sh);
-	luax_pushtype(L, GRAPHICS_QUAD_ID, quad);
+	luax_pushtype(L, quad);
 	quad->release();
 	return 1;
 }
@@ -633,7 +633,7 @@ int w_newFont(lua_State *L)
 	Font *font = nullptr;
 
 	// Convert to Rasterizer, if necessary.
-	if (!luax_istype(L, 1, FONT_RASTERIZER_ID))
+	if (!luax_istype(L, 1, love::font::Rasterizer::type))
 	{
 		std::vector<int> idxs;
 		for (int i = 0; i < lua_gettop(L); i++)
@@ -642,14 +642,14 @@ int w_newFont(lua_State *L)
 		luax_convobj(L, &idxs[0], (int) idxs.size(), "font", "newRasterizer");
 	}
 
-	love::font::Rasterizer *rasterizer = luax_checktype<love::font::Rasterizer>(L, 1, FONT_RASTERIZER_ID);
+	love::font::Rasterizer *rasterizer = luax_checktype<love::font::Rasterizer>(L, 1);
 
 	luax_catchexcept(L, [&]() {
 		font = instance()->newFont(rasterizer, instance()->getDefaultFilter()); }
 	);
 
 	// Push the type.
-	luax_pushtype(L, GRAPHICS_FONT_ID, font);
+	luax_pushtype(L, font);
 	font->release();
 	return 1;
 }
@@ -662,19 +662,19 @@ int w_newImageFont(lua_State *L)
 	Texture::Filter filter = instance()->getDefaultFilter();
 
 	// Convert to ImageData if necessary.
-	if (luax_istype(L, 1, GRAPHICS_IMAGE_ID))
+	if (luax_istype(L, 1, Image::type))
 	{
-		Image *i = luax_checktype<Image>(L, 1, GRAPHICS_IMAGE_ID);
+		Image *i = luax_checktype<Image>(L, 1);
 		filter = i->getFilter();
 		const auto &idlevels = i->getImageData();
 		if (idlevels.empty())
 			return luaL_argerror(L, 1, "Image must not be compressed.");
-		luax_pushtype(L, IMAGE_IMAGE_DATA_ID, idlevels[0].get());
+		luax_pushtype(L, idlevels[0].get());
 		lua_replace(L, 1);
 	}
 
 	// Convert to Rasterizer if necessary.
-	if (!luax_istype(L, 1, FONT_RASTERIZER_ID))
+	if (!luax_istype(L, 1, love::font::Rasterizer::type))
 	{
 		luaL_checktype(L, 2, LUA_TSTRING);
 
@@ -685,13 +685,13 @@ int w_newImageFont(lua_State *L)
 		luax_convobj(L, &idxs[0], (int) idxs.size(), "font", "newImageRasterizer");
 	}
 
-	love::font::Rasterizer *rasterizer = luax_checktype<love::font::Rasterizer>(L, 1, FONT_RASTERIZER_ID);
+	love::font::Rasterizer *rasterizer = luax_checktype<love::font::Rasterizer>(L, 1);
 
 	// Create the font.
 	Font *font = instance()->newFont(rasterizer, filter);
 
 	// Push the type.
-	luax_pushtype(L, GRAPHICS_FONT_ID, font);
+	luax_pushtype(L, font);
 	font->release();
 	return 1;
 }
@@ -715,7 +715,7 @@ int w_newSpriteBatch(lua_State *L)
 		[&](){ t = instance()->newSpriteBatch(texture, size, usage); }
 	);
 
-	luax_pushtype(L, GRAPHICS_SPRITE_BATCH_ID, t);
+	luax_pushtype(L, t);
 	t->release();
 	return 1;
 }
@@ -734,7 +734,7 @@ int w_newParticleSystem(lua_State *L)
 		[&](){ t = instance()->newParticleSystem(texture, int(size)); }
 	);
 
-	luax_pushtype(L, GRAPHICS_PARTICLE_SYSTEM_ID, t);
+	luax_pushtype(L, t);
 	t->release();
 	return 1;
 }
@@ -761,7 +761,7 @@ int w_newCanvas(lua_State *L)
 	if (canvas == nullptr)
 		return luaL_error(L, "Canvas not created, but no error thrown. I don't even...");
 
-	luax_pushtype(L, GRAPHICS_CANVAS_ID, canvas);
+	luax_pushtype(L, canvas);
 	canvas->release();
 	return 1;
 }
@@ -854,7 +854,7 @@ int w_newShader(lua_State *L)
 	try
 	{
 		Shader *shader = instance()->newShader(source);
-		luax_pushtype(L, GRAPHICS_SHADER_ID, shader);
+		luax_pushtype(L, shader);
 		shader->release();
 	}
 	catch (love::Exception &e)
@@ -1003,10 +1003,10 @@ static Mesh *newCustomMesh(lua_State *L)
 		int vertexcount = (int) luaL_checknumber(L, 2);
 		luax_catchexcept(L, [&](){ t = instance()->newMesh(vertexformat, vertexcount, drawmode, usage); });
 	}
-	else if (luax_istype(L, 2, DATA_ID))
+	else if (luax_istype(L, 2, Data::type))
 	{
 		// Vertex data comes directly from a Data object.
-		Data *data = luax_checktype<Data>(L, 2, DATA_ID);
+		Data *data = luax_checktype<Data>(L, 2);
 		luax_catchexcept(L, [&](){ t = instance()->newMesh(vertexformat, data->getData(), data->getSize(), drawmode, usage); });
 	}
 	else
@@ -1086,7 +1086,7 @@ int w_newMesh(lua_State *L)
 	else
 		t = newStandardMesh(L);
 
-	luax_pushtype(L, GRAPHICS_MESH_ID, t);
+	luax_pushtype(L, t);
 	t->release();
 	return 1;
 }
@@ -1108,7 +1108,7 @@ int w_newText(lua_State *L)
 		luax_catchexcept(L, [&](){ t = instance()->newText(font, text); });
 	}
 
-	luax_pushtype(L, GRAPHICS_TEXT_ID, t);
+	luax_pushtype(L, t);
 	t->release();
 	return 1;
 }
@@ -1117,14 +1117,14 @@ int w_newVideo(lua_State *L)
 {
 	luax_checkgraphicscreated(L);
 
-	if (!luax_istype(L, 1, VIDEO_VIDEO_STREAM_ID))
+	if (!luax_istype(L, 1, love::video::VideoStream::type))
 		luax_convobj(L, 1, "video", "newVideoStream");
 
-	auto stream = luax_checktype<love::video::VideoStream>(L, 1, VIDEO_VIDEO_STREAM_ID);
+	auto stream = luax_checktype<love::video::VideoStream>(L, 1);
 	Video *video = nullptr;
 
 	luax_catchexcept(L, [&]() { video = instance()->newVideo(stream); });
-	luax_pushtype(L, GRAPHICS_VIDEO_ID, video);
+	luax_pushtype(L, video);
 	video->release();
 	return 1;
 }
@@ -1204,14 +1204,14 @@ int w_getBackgroundColor(lua_State *L)
 int w_setNewFont(lua_State *L)
 {
 	int ret = w_newFont(L);
-	Font *font = luax_checktype<Font>(L, -1, GRAPHICS_FONT_ID);
+	Font *font = luax_checktype<Font>(L, -1);
 	instance()->setFont(font);
 	return ret;
 }
 
 int w_setFont(lua_State *L)
 {
-	Font *font = luax_checktype<Font>(L, 1, GRAPHICS_FONT_ID);
+	Font *font = luax_checktype<Font>(L, 1);
 	instance()->setFont(font);
 	return 0;
 }
@@ -1221,7 +1221,7 @@ int w_getFont(lua_State *L)
 	Font *f = nullptr;
 	luax_catchexcept(L, [&](){ f = instance()->getFont(); });
 
-	luax_pushtype(L, GRAPHICS_FONT_ID, f);
+	luax_pushtype(L, f);
 	return 1;
 }
 
@@ -1463,7 +1463,7 @@ int w_getShader(lua_State *L)
 {
 	Shader *shader = instance()->getShader();
 	if (shader)
-		luax_pushtype(L, GRAPHICS_SHADER_ID, shader);
+		luax_pushtype(L, shader);
 	else
 		lua_pushnil(L);
 
@@ -1626,10 +1626,10 @@ int w_draw(lua_State *L)
 	Quad *quad = nullptr;
 	int startidx = 2;
 
-	if (luax_istype(L, 2, GRAPHICS_QUAD_ID))
+	if (luax_istype(L, 2, Quad::type))
 	{
 		texture = luax_checktexture(L, 1);
-		quad = luax_totype<Quad>(L, 2, GRAPHICS_QUAD_ID);
+		quad = luax_totype<Quad>(L, 2);
 		startidx = 3;
 	}
 	else if (lua_isnil(L, 2) && !lua_isnoneornil(L, 3))
@@ -1638,13 +1638,13 @@ int w_draw(lua_State *L)
 	}
 	else
 	{
-		drawable = luax_checktype<Drawable>(L, 1, GRAPHICS_DRAWABLE_ID);
+		drawable = luax_checktype<Drawable>(L, 1);
 		startidx = 2;
 	}
 
-	if (luax_istype(L, startidx, MATH_TRANSFORM_ID))
+	if (luax_istype(L, startidx, math::Transform::type))
 	{
-		math::Transform *tf = luax_totype<math::Transform>(L, startidx, MATH_TRANSFORM_ID);
+		math::Transform *tf = luax_totype<math::Transform>(L, startidx);
 		luax_catchexcept(L, [&]() {
 			if (texture && quad)
 				instance()->drawq(texture, quad, tf->getMatrix());
@@ -1682,9 +1682,9 @@ int w_print(lua_State *L)
 	std::vector<Font::ColoredString> str;
 	luax_checkcoloredstring(L, 1, str);
 
-	if (luax_istype(L, 2, MATH_TRANSFORM_ID))
+	if (luax_istype(L, 2, math::Transform::type))
 	{
-		math::Transform *tf = luax_totype<math::Transform>(L, 2, MATH_TRANSFORM_ID);
+		math::Transform *tf = luax_totype<math::Transform>(L, 2);
 		luax_catchexcept(L, [&](){ instance()->print(str, tf->getMatrix()); });
 	}
 	else
@@ -1716,9 +1716,9 @@ int w_printf(lua_State *L)
 
 	int formatidx = 4;
 
-	if (luax_istype(L, 2, MATH_TRANSFORM_ID))
+	if (luax_istype(L, 2, math::Transform::type))
 	{
-		math::Transform *tf = luax_totype<math::Transform>(L, 2, MATH_TRANSFORM_ID);
+		math::Transform *tf = luax_totype<math::Transform>(L, 2);
 		m = tf->getMatrix();
 		formatidx = 3;
 	}
@@ -2047,9 +2047,9 @@ int w_push(lua_State *L)
 
 	luax_catchexcept(L, [&](){ instance()->push(stype); });
 
-	if (luax_istype(L, 2, MATH_TRANSFORM_ID))
+	if (luax_istype(L, 2, math::Transform::type))
 	{
-		math::Transform *t = luax_totype<math::Transform>(L, 2, MATH_TRANSFORM_ID);
+		math::Transform *t = luax_totype<math::Transform>(L, 2);
 		instance()->applyTransform(t);
 	}
 
@@ -2250,7 +2250,7 @@ static const luaL_Reg functions[] =
 
 static int luaopen_drawable(lua_State *L)
 {
-	return luax_register_type(L, GRAPHICS_DRAWABLE_ID, "Drawable", nullptr);
+	return luax_register_type(L, &Drawable::type, nullptr);
 }
 
 // Types for this module.
@@ -2284,7 +2284,7 @@ extern "C" int luaopen_love_graphics(lua_State *L)
 	WrappedModule w;
 	w.module = instance;
 	w.name = "graphics";
-	w.type = MODULE_GRAPHICS_ID;
+	w.type = &Graphics::type;
 	w.functions = functions;
 	w.types = types;
 

+ 4 - 4
src/modules/graphics/opengl/wrap_Image.cpp

@@ -30,7 +30,7 @@ namespace opengl
 
 Image *luax_checkimage(lua_State *L, int idx)
 {
-	return luax_checktype<Image>(L, idx, GRAPHICS_IMAGE_ID);
+	return luax_checktype<Image>(L, idx);
 }
 
 int w_Image_setMipmapFilter(lua_State *L)
@@ -98,7 +98,7 @@ int w_Image_getData(lua_State *L)
 	{
 		for (const auto &cdata : i->getCompressedData())
 		{
-			luax_pushtype(L, IMAGE_COMPRESSED_IMAGE_DATA_ID, cdata.get());
+			luax_pushtype(L, cdata.get());
 			n++;
 		}
 	}
@@ -106,7 +106,7 @@ int w_Image_getData(lua_State *L)
 	{
 		for (const auto &data : i->getImageData())
 		{
-			luax_pushtype(L, IMAGE_IMAGE_DATA_ID, data.get());
+			luax_pushtype(L, data.get());
 			n++;
 		}
 	}
@@ -150,7 +150,7 @@ static const luaL_Reg w_Image_functions[] =
 
 extern "C" int luaopen_image(lua_State *L)
 {
-	return luax_register_type(L, GRAPHICS_IMAGE_ID, "Image", w_Texture_functions, w_Image_functions, nullptr);
+	return luax_register_type(L, &Image::type, w_Texture_functions, w_Image_functions, nullptr);
 }
 
 } // opengl

+ 6 - 6
src/modules/graphics/opengl/wrap_Mesh.cpp

@@ -37,7 +37,7 @@ namespace opengl
 
 Mesh *luax_checkmesh(lua_State *L, int idx)
 {
-	return luax_checktype<Mesh>(L, idx, GRAPHICS_MESH_ID);
+	return luax_checktype<Mesh>(L, idx);
 }
 
 static inline size_t writeByteData(lua_State *L, int startidx, int components, char *data)
@@ -117,9 +117,9 @@ int w_Mesh_setVertices(lua_State *L)
 	size_t stride = t->getVertexStride();
 	size_t byteoffset = vertoffset * stride;
 
-	if (luax_istype(L, 2, DATA_ID))
+	if (luax_istype(L, 2, Data::type))
 	{
-		Data *d = luax_checktype<Data>(L, 2, DATA_ID);
+		Data *d = luax_checktype<Data>(L, 2);
 
 		size_t datasize = std::min(d->getSize(), (t->getVertexCount() - vertoffset) * stride);
 		char *bytedata = (char *) t->mapVertexData() + byteoffset;
@@ -448,9 +448,9 @@ int w_Mesh_getTexture(lua_State *L)
 
 	// FIXME: big hack right here.
 	if (typeid(*tex) == typeid(Image))
-		luax_pushtype(L, GRAPHICS_IMAGE_ID, tex);
+		luax_pushtype(L, Image::type, tex);
 	else if (typeid(*tex) == typeid(Canvas))
-		luax_pushtype(L, GRAPHICS_CANVAS_ID, tex);
+		luax_pushtype(L, Canvas::type, tex);
 	else
 		return luaL_error(L, "Unable to determine texture type.");
 
@@ -540,7 +540,7 @@ static const luaL_Reg w_Mesh_functions[] =
 
 extern "C" int luaopen_mesh(lua_State *L)
 {
-	return luax_register_type(L, GRAPHICS_MESH_ID, "Mesh", w_Mesh_functions, nullptr);
+	return luax_register_type(L, &Mesh::type, w_Mesh_functions, nullptr);
 }
 
 } // opengl

+ 8 - 8
src/modules/graphics/opengl/wrap_ParticleSystem.cpp

@@ -41,7 +41,7 @@ namespace opengl
 
 ParticleSystem *luax_checkparticlesystem(lua_State *L, int idx)
 {
-	return luax_checktype<ParticleSystem>(L, idx, GRAPHICS_PARTICLE_SYSTEM_ID);
+	return luax_checktype<ParticleSystem>(L, idx);
 }
 
 int w_ParticleSystem_clone(lua_State *L)
@@ -51,7 +51,7 @@ int w_ParticleSystem_clone(lua_State *L)
 	ParticleSystem *clone = nullptr;
 	luax_catchexcept(L, [&](){ clone = t->clone(); });
 
-	luax_pushtype(L, GRAPHICS_PARTICLE_SYSTEM_ID, clone);
+	luax_pushtype(L, clone);
 	clone->release();
 	return 1;
 }
@@ -71,9 +71,9 @@ int w_ParticleSystem_getTexture(lua_State *L)
 
 	// FIXME: big hack right here.
 	if (typeid(*tex) == typeid(Image))
-		luax_pushtype(L, GRAPHICS_IMAGE_ID, tex);
+		luax_pushtype(L, Image::type, tex);
 	else if (typeid(*tex) == typeid(Canvas))
-		luax_pushtype(L, GRAPHICS_CANVAS_ID, tex);
+		luax_pushtype(L, Canvas::type, tex);
 	else
 		return luaL_error(L, "Unable to determine texture type.");
 
@@ -584,7 +584,7 @@ int w_ParticleSystem_setQuads(lua_State *L)
 		{
 			lua_rawgeti(L, 2, i);
 
-			Quad *q = luax_checktype<Quad>(L, -1, GRAPHICS_QUAD_ID);
+			Quad *q = luax_checktype<Quad>(L, -1);
 			quads.push_back(q);
 
 			lua_pop(L, 1);
@@ -594,7 +594,7 @@ int w_ParticleSystem_setQuads(lua_State *L)
 	{
 		for (int i = 2; i <= lua_gettop(L); i++)
 		{
-			Quad *q = luax_checktype<Quad>(L, i, GRAPHICS_QUAD_ID);
+			Quad *q = luax_checktype<Quad>(L, i);
 			quads.push_back(q);
 		}
 	}
@@ -612,7 +612,7 @@ int w_ParticleSystem_getQuads(lua_State *L)
 
 	for (int i = 0; i < (int) quads.size(); i++)
 	{
-		luax_pushtype(L, GRAPHICS_QUAD_ID, quads[i]);
+		luax_pushtype(L, quads[i]);
 		lua_rawseti(L, -2, i + 1);
 	}
 
@@ -772,7 +772,7 @@ static const luaL_Reg w_ParticleSystem_functions[] =
 
 extern "C" int luaopen_particlesystem(lua_State *L)
 {
-	return luax_register_type(L, GRAPHICS_PARTICLE_SYSTEM_ID, "ParticleSystem", w_ParticleSystem_functions, nullptr);
+	return luax_register_type(L, &ParticleSystem::type, w_ParticleSystem_functions, nullptr);
 }
 
 } // opengl

+ 4 - 4
src/modules/graphics/opengl/wrap_Shader.cpp

@@ -36,7 +36,7 @@ namespace opengl
 
 Shader *luax_checkshader(lua_State *L, int idx)
 {
-	return luax_checktype<Shader>(L, idx, GRAPHICS_SHADER_ID);
+	return luax_checktype<Shader>(L, idx);
 }
 
 int w_Shader_getWarnings(lua_State *L)
@@ -165,9 +165,9 @@ int w_Shader_sendMatrices(lua_State *L, int startidx, Shader *shader, const Shad
 
 	for (int i = 0; i < count; i++)
 	{
-		if (columns == 4 && rows == 4 && luax_istype(L, startidx + i, MATH_TRANSFORM_ID))
+		if (columns == 4 && rows == 4 && luax_istype(L, startidx + i, math::Transform::type))
 		{
-			math::Transform *t = luax_totype<math::Transform>(L, startidx + i, MATH_TRANSFORM_ID);
+			math::Transform *t = luax_totype<math::Transform>(L, startidx + i);
 			memcpy(&values[i * 16], t->getMatrix().getElements(), sizeof(float) * 16);
 			continue;
 		}
@@ -328,7 +328,7 @@ static const luaL_Reg w_Shader_functions[] =
 
 extern "C" int luaopen_shader(lua_State *L)
 {
-	return luax_register_type(L, GRAPHICS_SHADER_ID, "Shader", w_Shader_functions, nullptr);
+	return luax_register_type(L, &Shader::type, w_Shader_functions, nullptr);
 }
 
 } // opengl

+ 9 - 9
src/modules/graphics/opengl/wrap_SpriteBatch.cpp

@@ -37,24 +37,24 @@ namespace opengl
 
 SpriteBatch *luax_checkspritebatch(lua_State *L, int idx)
 {
-	return luax_checktype<SpriteBatch>(L, idx, GRAPHICS_SPRITE_BATCH_ID);
+	return luax_checktype<SpriteBatch>(L, idx);
 }
 
 static inline int w_SpriteBatch_add_or_set(lua_State *L, SpriteBatch *t, int startidx, int index)
 {
 	Quad *quad = nullptr;
 
-	if (luax_istype(L, startidx, GRAPHICS_QUAD_ID))
+	if (luax_istype(L, startidx, Quad::type))
 	{
-		quad = luax_totype<Quad>(L, startidx, GRAPHICS_QUAD_ID);
+		quad = luax_totype<Quad>(L, startidx);
 		startidx++;
 	}
 	else if (lua_isnil(L, startidx) && !lua_isnoneornil(L, startidx + 1))
 		return luax_typerror(L, startidx, "Quad");
 
-	if (luax_istype(L, startidx, MATH_TRANSFORM_ID))
+	if (luax_istype(L, startidx, math::Transform::type))
 	{
-		math::Transform *tf = luax_totype<math::Transform>(L, startidx, MATH_TRANSFORM_ID);
+		math::Transform *tf = luax_totype<math::Transform>(L, startidx);
 		luax_catchexcept(L, [&]() {
 			if (quad)
 				index = t->addq(quad, tf->getMatrix(), index);
@@ -136,9 +136,9 @@ int w_SpriteBatch_getTexture(lua_State *L)
 
 	// FIXME: big hack right here.
 	if (typeid(*tex) == typeid(Image))
-		luax_pushtype(L, GRAPHICS_IMAGE_ID, tex);
+		luax_pushtype(L, Image::type, tex);
 	else if (typeid(*tex) == typeid(Canvas))
-		luax_pushtype(L, GRAPHICS_CANVAS_ID, tex);
+		luax_pushtype(L, Canvas::type, tex);
 	else
 		return luaL_error(L, "Unable to determine texture type.");
 
@@ -215,7 +215,7 @@ int w_SpriteBatch_attachAttribute(lua_State *L)
 {
 	SpriteBatch *t = luax_checkspritebatch(L, 1);
 	const char *name = luaL_checkstring(L, 2);
-	Mesh *m = luax_checktype<Mesh>(L, 3, GRAPHICS_MESH_ID);
+	Mesh *m = luax_checktype<Mesh>(L, 3);
 
 	luax_catchexcept(L, [&](){ t->attachAttribute(name, m); });
 	return 0;
@@ -271,7 +271,7 @@ static const luaL_Reg w_SpriteBatch_functions[] =
 
 extern "C" int luaopen_spritebatch(lua_State *L)
 {
-	return luax_register_type(L, GRAPHICS_SPRITE_BATCH_ID, "SpriteBatch", w_SpriteBatch_functions, nullptr);
+	return luax_register_type(L, &SpriteBatch::type, w_SpriteBatch_functions, nullptr);
 }
 
 } // opengl

+ 8 - 8
src/modules/graphics/opengl/wrap_Text.cpp

@@ -30,7 +30,7 @@ namespace opengl
 
 Text *luax_checktext(lua_State *L, int idx)
 {
-	return luax_checktype<Text>(L, idx, GRAPHICS_TEXT_ID);
+	return luax_checktype<Text>(L, idx);
 }
 
 void luax_checkcoloredstring(lua_State *L, int idx, std::vector<Font::ColoredString> &strings)
@@ -132,9 +132,9 @@ int w_Text_add(lua_State *L)
 	std::vector<Font::ColoredString> text;
 	luax_checkcoloredstring(L, 2, text);
 
-	if (luax_istype(L, 3, MATH_TRANSFORM_ID))
+	if (luax_istype(L, 3, math::Transform::type))
 	{
-		math::Transform *tf = luax_totype<math::Transform>(L, 3, MATH_TRANSFORM_ID);
+		math::Transform *tf = luax_totype<math::Transform>(L, 3);
 		luax_catchexcept(L, [&](){ index = t->add(text, tf->getMatrix()); });
 	}
 	else
@@ -174,9 +174,9 @@ int w_Text_addf(lua_State *L)
 	if (!Font::getConstant(alignstr, align))
 		return luaL_error(L, "Invalid align mode: %s", alignstr);
 
-	if (luax_istype(L, 5, MATH_TRANSFORM_ID))
+	if (luax_istype(L, 5, math::Transform::type))
 	{
-		math::Transform *tf = luax_totype<math::Transform>(L, 5, MATH_TRANSFORM_ID);
+		math::Transform *tf = luax_totype<math::Transform>(L, 5);
 		luax_catchexcept(L, [&](){ index = t->addf(text, wrap, align, tf->getMatrix()); });
 	}
 	else
@@ -209,7 +209,7 @@ int w_Text_clear(lua_State *L)
 int w_Text_setFont(lua_State *L)
 {
 	Text *t = luax_checktext(L, 1);
-	Font *f = luax_checktype<Font>(L, 2, GRAPHICS_FONT_ID);
+	Font *f = luax_checktype<Font>(L, 2);
 	luax_catchexcept(L, [&](){ t->setFont(f); });
 	return 0;
 }
@@ -218,7 +218,7 @@ int w_Text_getFont(lua_State *L)
 {
 	Text *t = luax_checktext(L, 1);
 	Font *f = t->getFont();
-	luax_pushtype(L, GRAPHICS_FONT_ID, f);
+	luax_pushtype(L, f);
 	return 1;
 }
 
@@ -264,7 +264,7 @@ static const luaL_Reg w_Text_functions[] =
 
 extern "C" int luaopen_text(lua_State *L)
 {
-	return luax_register_type(L, GRAPHICS_TEXT_ID, "Text", w_Text_functions, nullptr);
+	return luax_register_type(L, &Text::type, w_Text_functions, nullptr);
 }
 
 } // opengl

+ 6 - 6
src/modules/graphics/opengl/wrap_Video.cpp

@@ -34,13 +34,13 @@ namespace opengl
 
 Video *luax_checkvideo(lua_State *L, int idx)
 {
-	return luax_checktype<Video>(L, idx, GRAPHICS_VIDEO_ID);
+	return luax_checktype<Video>(L, idx);
 }
 
 int w_Video_getStream(lua_State *L)
 {
 	Video *video = luax_checkvideo(L, 1);
-	luax_pushtype(L, VIDEO_VIDEO_STREAM_ID, video->getStream());
+	luax_pushtype(L, video->getStream());
 	return 1;
 }
 
@@ -49,7 +49,7 @@ int w_Video_getSource(lua_State *L)
 	Video *video = luax_checkvideo(L, 1);
 	auto source = video->getSource();
 	if (source)
-		luax_pushtype(L, AUDIO_SOURCE_ID, video->getSource());
+		luax_pushtype(L, video->getSource());
 	else
 		lua_pushnil(L);
 	return 1;
@@ -62,7 +62,7 @@ int w_Video_setSource(lua_State *L)
 		video->setSource(nullptr);
 	else
 	{
-		auto source = luax_checktype<love::audio::Source>(L, 2, AUDIO_SOURCE_ID);
+		auto source = luax_checktype<love::audio::Source>(L, 2);
 		video->setSource(source);
 	}
 	return 0;
@@ -143,10 +143,10 @@ static const luaL_Reg functions[] =
 
 int luaopen_video(lua_State *L)
 {
-	int ret = luax_register_type(L, GRAPHICS_VIDEO_ID, "Video", functions, nullptr);
+	int ret = luax_register_type(L, &Video::type, functions, nullptr);
 
 	luaL_loadbuffer(L, video_lua, sizeof(video_lua), "Video.lua");
-	luax_gettypemetatable(L, GRAPHICS_VIDEO_ID);
+	luax_gettypemetatable(L, Video::type);
 	lua_call(L, 1, 0);
 
 	return ret;

+ 2 - 2
src/modules/graphics/wrap_Quad.cpp

@@ -28,7 +28,7 @@ namespace graphics
 
 Quad *luax_checkquad(lua_State *L, int idx)
 {
-	return luax_checktype<Quad>(L, idx, GRAPHICS_QUAD_ID);
+	return luax_checktype<Quad>(L, idx);
 }
 
 int w_Quad_setViewport(lua_State *L)
@@ -84,7 +84,7 @@ static const luaL_Reg w_Quad_functions[] =
 
 extern "C" int luaopen_quad(lua_State *L)
 {
-	return luax_register_type(L, GRAPHICS_QUAD_ID, "Quad", w_Quad_functions, nullptr);
+	return luax_register_type(L, &Quad::type, w_Quad_functions, nullptr);
 }
 
 } // graphics

+ 2 - 2
src/modules/graphics/wrap_Texture.cpp

@@ -27,7 +27,7 @@ namespace graphics
 
 Texture *luax_checktexture(lua_State *L, int idx)
 {
-	return luax_checktype<Texture>(L, idx, GRAPHICS_TEXTURE_ID);
+	return luax_checktype<Texture>(L, idx);
 }
 
 int w_Texture_getWidth(lua_State *L)
@@ -139,7 +139,7 @@ const luaL_Reg w_Texture_functions[] =
 
 extern "C" int luaopen_texture(lua_State *L)
 {
-	return luax_register_type(L, GRAPHICS_TEXTURE_ID, "Texture", w_Texture_functions, nullptr);
+	return luax_register_type(L, &Texture::type, w_Texture_functions, nullptr);
 }
 
 } // graphics

+ 2 - 0
src/modules/image/CompressedImageData.cpp

@@ -25,6 +25,8 @@ namespace love
 namespace image
 {
 
+love::Type CompressedImageData::type("CompressedImageData", &Data::type);
+
 CompressedImageData::CompressedImageData()
 	: format(PIXELFORMAT_UNKNOWN)
 	, sRGB(false)

+ 2 - 0
src/modules/image/CompressedImageData.h

@@ -44,6 +44,8 @@ class CompressedImageData : public Data
 {
 public:
 
+	static love::Type type;
+
 	// Compressed image data can have multiple mipmap levels, each represented
 	// by a sub-image.
 	struct SubImage

+ 32 - 0
src/modules/image/Image.cpp

@@ -0,0 +1,32 @@
+/**
+ * Copyright (c) 2006-2016 LOVE Development Team
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.  In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ *    claim that you wrote the original software. If you use this software
+ *    in a product, an acknowledgment in the product documentation would be
+ *    appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ *    misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ **/
+
+// LOVE
+#include "Image.h"
+
+namespace love
+{
+namespace image
+{
+
+love::Type Image::type("image", &Module::type);
+
+} // image
+} // love

+ 2 - 0
src/modules/image/Image.h

@@ -44,6 +44,8 @@ class Image : public Module
 {
 public:
 
+	static love::Type type;
+
 	virtual ~Image() {}
 
 	// Implements Module.

+ 2 - 0
src/modules/image/ImageData.cpp

@@ -27,6 +27,8 @@ namespace love
 namespace image
 {
 
+love::Type ImageData::type("ImageData", &Data::type);
+
 ImageData::ImageData()
 	: format(PIXELFORMAT_UNKNOWN)
 	, width(0)

+ 2 - 0
src/modules/image/ImageData.h

@@ -59,6 +59,8 @@ class ImageData : public Data
 {
 public:
 
+	static love::Type type;
+
 	enum EncodedFormat
 	{
 		ENCODED_TGA,

+ 2 - 2
src/modules/image/wrap_CompressedImageData.cpp

@@ -28,7 +28,7 @@ namespace image
 
 CompressedImageData *luax_checkcompressedimagedata(lua_State *L, int idx)
 {
-	return luax_checktype<CompressedImageData>(L, idx, IMAGE_COMPRESSED_IMAGE_DATA_ID);
+	return luax_checktype<CompressedImageData>(L, idx);
 }
 
 int w_CompressedImageData_getWidth(lua_State *L)
@@ -106,7 +106,7 @@ static const luaL_Reg w_CompressedImageData_functions[] =
 
 extern "C" int luaopen_compressedimagedata(lua_State *L)
 {
-	return luax_register_type(L, IMAGE_COMPRESSED_IMAGE_DATA_ID, "CompressedImageData", w_Data_functions, w_CompressedImageData_functions, nullptr);
+	return luax_register_type(L, &CompressedImageData::type, w_Data_functions, w_CompressedImageData_functions, nullptr);
 }
 
 } // image

+ 4 - 4
src/modules/image/wrap_Image.cpp

@@ -73,7 +73,7 @@ int w_newImageData(lua_State *L)
 			memcpy(t->getData(), bytes, t->getSize());
 		}
 
-		luax_pushtype(L, IMAGE_IMAGE_DATA_ID, t);
+		luax_pushtype(L, t);
 		t->release();
 		return 1;
 	}
@@ -87,7 +87,7 @@ int w_newImageData(lua_State *L)
 			[&](bool) { data->release(); }
 		);
 
-		luax_pushtype(L, IMAGE_IMAGE_DATA_ID, t);
+		luax_pushtype(L, t);
 		t->release();
 		return 1;
 	}
@@ -107,7 +107,7 @@ int w_newCompressedData(lua_State *L)
 		[&](bool) { data->release(); }
 	);
 
-	luax_pushtype(L, IMAGE_COMPRESSED_IMAGE_DATA_ID, t);
+	luax_pushtype(L, CompressedImageData::type, t);
 	t->release();
 	return 1;
 }
@@ -151,7 +151,7 @@ extern "C" int luaopen_love_image(lua_State *L)
 	WrappedModule w;
 	w.module = instance;
 	w.name = "image";
-	w.type = MODULE_IMAGE_ID;
+	w.type = &Image::type;
 	w.functions = functions;
 	w.types = types;
 

+ 4 - 4
src/modules/image/wrap_ImageData.cpp

@@ -40,7 +40,7 @@ namespace image
 
 ImageData *luax_checkimagedata(lua_State *L, int idx)
 {
-	return luax_checktype<ImageData>(L, idx, IMAGE_IMAGE_DATA_ID);
+	return luax_checktype<ImageData>(L, idx);
 }
 
 int w_ImageData_getFormat(lua_State *L)
@@ -269,7 +269,7 @@ int w_ImageData_encode(lua_State *L)
 	love::filesystem::FileData *filedata = nullptr;
 	luax_catchexcept(L, [&](){ filedata = t->encode(format, filename.c_str()); });
 
-	luax_pushtype(L, FILESYSTEM_FILE_DATA_ID, filedata);
+	luax_pushtype(L, filedata);
 	filedata->release();
 
 	if (hasfilename)
@@ -363,9 +363,9 @@ extern "C" int luaopen_imagedata(lua_State *L)
 	pushFormats[PIXELFORMAT_RGBA16F] = luax_pushpixel_rgba16f;
 	pushFormats[PIXELFORMAT_RGBA32F] = luax_pushpixel_rgba32f;
 
-	int ret = luax_register_type(L, IMAGE_IMAGE_DATA_ID, "ImageData", w_Data_functions, w_ImageData_functions, nullptr);
+	int ret = luax_register_type(L, &ImageData::type, w_Data_functions, w_ImageData_functions, nullptr);
 
-	luax_gettypemetatable(L, IMAGE_IMAGE_DATA_ID);
+	luax_gettypemetatable(L, ImageData::type);
 
 	// Load and execute ImageData.lua, sending the metatable and the ffi
 	// functions struct pointer as arguments.

+ 2 - 0
src/modules/joystick/Joystick.cpp

@@ -29,6 +29,8 @@ namespace love
 namespace joystick
 {
 
+love::Type Joystick::type("Joystick", &Object::type);
+
 float Joystick::clampval(float x)
 {
 	if (fabsf(x) < 0.01)

+ 2 - 0
src/modules/joystick/Joystick.h

@@ -38,6 +38,8 @@ class Joystick : public Object
 {
 public:
 
+	static love::Type type;
+
 	// Joystick hat values.
 	enum Hat
 	{

+ 2 - 2
src/modules/joystick/wrap_Joystick.cpp

@@ -31,7 +31,7 @@ namespace joystick
 
 Joystick *luax_checkjoystick(lua_State *L, int idx)
 {
-	return luax_checktype<Joystick>(L, idx, JOYSTICK_JOYSTICK_ID);
+	return luax_checktype<Joystick>(L, idx);
 }
 
 int w_Joystick_isConnected(lua_State *L)
@@ -296,7 +296,7 @@ static const luaL_Reg w_Joystick_functions[] =
 
 extern "C" int luaopen_joystick(lua_State *L)
 {
-	return luax_register_type(L, JOYSTICK_JOYSTICK_ID, "Joystick", w_Joystick_functions, nullptr);
+	return luax_register_type(L, &Joystick::type, w_Joystick_functions, nullptr);
 }
 
 } // joystick

+ 2 - 2
src/modules/joystick/wrap_JoystickModule.cpp

@@ -40,7 +40,7 @@ int w_getJoysticks(lua_State *L)
 	for (int i = 0; i < stickcount; i++)
 	{
 		Joystick *stick = instance()->getJoystick(i);
-		luax_pushtype(L, JOYSTICK_JOYSTICK_ID, stick);
+		luax_pushtype(L, stick);
 		lua_rawseti(L, -2, i + 1);
 	}
 
@@ -254,7 +254,7 @@ extern "C" int luaopen_love_joystick(lua_State *L)
 	WrappedModule w;
 	w.module = instance;
 	w.name = "joystick";
-	w.type = MODULE_ID;
+	w.type = &Module::type;
 	w.functions = functions;
 	w.types = types;
 

+ 1 - 1
src/modules/keyboard/wrap_Keyboard.cpp

@@ -201,7 +201,7 @@ extern "C" int luaopen_love_keyboard(lua_State *L)
 	WrappedModule w;
 	w.module = instance;
 	w.name = "keyboard";
-	w.type = MODULE_ID;
+	w.type = &Module::type;
 	w.functions = functions;
 	w.types = 0;
 

+ 2 - 0
src/modules/math/BezierCurve.cpp

@@ -83,6 +83,8 @@ namespace love
 namespace math
 {
 
+love::Type BezierCurve::type("BezierCurve", &Object::type);
+
 BezierCurve::BezierCurve(const vector<Vector> &pts)
 	: controlPoints(pts)
 {

+ 2 - 0
src/modules/math/BezierCurve.h

@@ -35,6 +35,8 @@ class BezierCurve : public Object
 {
 public:
 
+	static love::Type type;
+
 	/**
 	 * @param controlPoints Control polygon of the curve.
 	 **/

+ 2 - 0
src/modules/math/CompressedData.cpp

@@ -26,6 +26,8 @@ namespace love
 namespace math
 {
 
+love::Type CompressedData::type("CompressedData", &Data::type);
+
 CompressedData::CompressedData(Compressor::Format format, char *cdata, size_t compressedsize, size_t rawsize, bool own)
 	: format(format)
 	, data(nullptr)

Энэ ялгаанд хэт олон файл өөрчлөгдсөн тул зарим файлыг харуулаагүй болно