Imported some of the dynamiccore branch from love-experiments:

- Type names for love's Lua objects are specified as an argument to luax_register_type, rather than being statically defined in an array.

- luax_register_type takes a variable number of method array arguments, for registering superclass methods without copying them into the subclass' method array.

Also removed most of the header declarations for wrapper functions.
This commit is contained in:
Alex Szpakowski
2015-11-29 20:38:12 -04:00
parent 77998c707d
commit 2c4e713114
124 changed files with 251 additions and 1300 deletions
+1 -3
View File
@@ -24,8 +24,6 @@
namespace love
{
extern StringMap<Type, TYPE_MAX_ENUM> types;
static love::Type extractudatatype(lua_State *L, int idx)
{
Type t = INVALID_ID;
@@ -36,7 +34,7 @@ static love::Type extractudatatype(lua_State *L, int idx)
lua_pushvalue(L, idx);
int result = lua_pcall(L, 1, 1, 0);
if (result == 0)
types.find(lua_tostring(L, -1), t);
getTypeName(lua_tostring(L, -1), t);
if (result == 0 || result == LUA_ERRRUN)
lua_pop(L, 1);
return t;
+23 -15
View File
@@ -216,6 +216,8 @@ 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);
// Put a reference to the C++ module in Lua.
luax_insistregistry(L, REGISTRY_MODULES);
@@ -270,12 +272,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 luaL_Reg *f, bool pushmetatable)
int luax_register_type(lua_State *L, love::Type type, const char *name, ...)
{
// Verify that this type name has a matching Type ID and type name mapping.
const char *tname = "Invalid";
if (!love::getType(type, tname))
printf("Missing type name entry for type ID %d\n", type);
love::addTypeName(type, name);
// Get the place for storing and re-using instantiated love types.
luax_getregistry(L, REGISTRY_OBJECTS);
@@ -302,7 +301,7 @@ int luax_register_type(lua_State *L, love::Type type, const luaL_Reg *f, bool pu
else
lua_pop(L, 1);
luaL_newmetatable(L, tname);
luaL_newmetatable(L, name);
// m.__index = m
lua_pushvalue(L, -1);
@@ -317,12 +316,12 @@ int luax_register_type(lua_State *L, love::Type type, const luaL_Reg *f, bool pu
lua_setfield(L, -2, "__eq");
// Add tostring function.
lua_pushstring(L, tname);
lua_pushstring(L, name);
lua_pushcclosure(L, w__tostring, 1);
lua_setfield(L, -2, "__tostring");
// Add type
lua_pushstring(L, tname);
lua_pushstring(L, name);
lua_pushcclosure(L, w__type, 1);
lua_setfield(L, -2, "type");
@@ -330,16 +329,25 @@ int luax_register_type(lua_State *L, love::Type type, const luaL_Reg *f, bool pu
lua_pushcfunction(L, w__typeOf);
lua_setfield(L, -2, "typeOf");
if (f != nullptr)
va_list fs;
va_start(fs, name);
for (const luaL_Reg *f = va_arg(fs, const luaL_Reg *); f; f = va_arg(fs, const luaL_Reg *))
luax_setfuncs(L, f);
if (pushmetatable)
return 1; // leave the metatable on the stack.
va_end(fs);
lua_pop(L, 1); // Pops metatable.
return 0;
}
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);
}
int luax_table_insert(lua_State *L, int tindex, int vindex, int pos)
{
if (tindex < 0)
@@ -403,7 +411,7 @@ void luax_rawnewtype(lua_State *L, love::Type type, love::Object *object)
u->type = type;
const char *name = "Invalid";
getType(type, name);
getTypeName(type, name);
luaL_newmetatable(L, name);
lua_setmetatable(L, -2);
@@ -670,7 +678,7 @@ 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::getType(argtname, t))
if (!love::getTypeName(argtname, t))
argtname = 0;
}
}
@@ -707,7 +715,7 @@ void luax_register(lua_State *L, const char *name, const luaL_Reg *l)
Type luax_type(lua_State *L, int idx)
{
Type t = INVALID_ID;
getType(luaL_checkstring(L, idx), t);
getTypeName(luaL_checkstring(L, idx), t);
return t;
}
+12 -7
View File
@@ -247,10 +247,15 @@ int luax_preload(lua_State *L, lua_CFunction f, const char *name);
/**
* Register a new type.
* @param type The type.
* @param f The list of member functions for the type.
* @param pushmetatable Whether to push the type's metatable to the stack.
* @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 luaL_Reg *f = nullptr, bool pushmetatable = false);
int luax_register_type(lua_State *L, love::Type type, const char *name, ...);
/**
* Pushes the metatable of the specified type onto the stack.
**/
void luax_gettypemetatable(lua_State *L, love::Type type);
/**
* Do a table.insert from C
@@ -434,7 +439,7 @@ T *luax_checktype(lua_State *L, int idx, love::Type type)
if (lua_type(L, idx) != LUA_TUSERDATA)
{
const char *name = "Invalid";
getType(type, name);
getTypeName(type, name);
luax_typerror(L, idx, name);
}
@@ -443,7 +448,7 @@ T *luax_checktype(lua_State *L, int idx, love::Type type)
if (!typeFlags[u->type][type])
{
const char *name = "Invalid";
getType(type, name);
getTypeName(type, name);
luax_typerror(L, idx, name);
}
@@ -454,7 +459,7 @@ template <typename T>
T *luax_getmodule(lua_State *L, love::Type type)
{
const char *name = "Invalid";
getType(type, name);
getTypeName(type, name);
luax_insistregistry(L, REGISTRY_MODULES);
lua_getfield(L, -1, name);
@@ -476,7 +481,7 @@ template <typename T>
T *luax_optmodule(lua_State *L, love::Type type)
{
const char *name = "Invalid";
getType(type, name);
getTypeName(type, name);
luax_insistregistry(L, REGISTRY_MODULES);
lua_getfield(L, -1, name);
+9 -90
View File
@@ -116,102 +116,21 @@ static const TypeBits *createTypeFlags()
const TypeBits *typeFlags = createTypeFlags();
StringMap<Type, TYPE_MAX_ENUM>::Entry typeEntries[] =
static StringMap<Type, TYPE_MAX_ENUM> types(nullptr, 0);
void addTypeName(Type type, const char *name)
{
{"Invalid", INVALID_ID},
const char *n;
if (!types.find(type, n))
types.add(name, type);
}
{"Object", OBJECT_ID},
{"Data", DATA_ID},
{"Module", MODULE_ID},
// Filesystem
{"File", FILESYSTEM_FILE_ID},
{"DroppedFile", FILESYSTEM_DROPPED_FILE_ID},
{"FileData", FILESYSTEM_FILE_DATA_ID},
// Font
{"GlyphData", FONT_GLYPH_DATA_ID},
{"Rasterizer", FONT_RASTERIZER_ID},
// Graphics
{"Drawable", GRAPHICS_DRAWABLE_ID},
{"Texture", GRAPHICS_TEXTURE_ID},
{"Image", GRAPHICS_IMAGE_ID},
{"Quad", GRAPHICS_QUAD_ID},
{"Font", GRAPHICS_FONT_ID},
{"ParticleSystem", GRAPHICS_PARTICLE_SYSTEM_ID},
{"SpriteBatch", GRAPHICS_SPRITE_BATCH_ID},
{"Canvas", GRAPHICS_CANVAS_ID},
{"Shader", GRAPHICS_SHADER_ID},
{"Mesh", GRAPHICS_MESH_ID},
{"Text", GRAPHICS_TEXT_ID},
// Image
{"ImageData", IMAGE_IMAGE_DATA_ID},
{"CompressedImageData", IMAGE_COMPRESSED_IMAGE_DATA_ID},
// Joystick
{"Joystick", JOYSTICK_JOYSTICK_ID},
// Math
{"RandomGenerator", MATH_RANDOM_GENERATOR_ID},
{"BezierCurve", MATH_BEZIER_CURVE_ID},
{"CompressedData", MATH_COMPRESSED_DATA_ID},
// Audio
{"Source", AUDIO_SOURCE_ID},
// Sound
{"SoundData", SOUND_SOUND_DATA_ID},
{"Decoder", SOUND_DECODER_ID},
// Mouse
{"Cursor", MOUSE_CURSOR_ID},
// Physics
{"World", PHYSICS_WORLD_ID},
{"Contact", PHYSICS_CONTACT_ID},
{"Body", PHYSICS_BODY_ID},
{"Fixture", PHYSICS_FIXTURE_ID},
{"Shape", PHYSICS_SHAPE_ID},
{"CircleShape", PHYSICS_CIRCLE_SHAPE_ID},
{"PolygonShape", PHYSICS_POLYGON_SHAPE_ID},
{"EdgeShape", PHYSICS_EDGE_SHAPE_ID},
{"ChainShape", PHYSICS_CHAIN_SHAPE_ID},
{"Joint", PHYSICS_JOINT_ID},
{"MouseJoint", PHYSICS_MOUSE_JOINT_ID},
{"DistanceJoint", PHYSICS_DISTANCE_JOINT_ID},
{"PrismaticJoint", PHYSICS_PRISMATIC_JOINT_ID},
{"RevoluteJoint", PHYSICS_REVOLUTE_JOINT_ID},
{"PulleyJoint", PHYSICS_PULLEY_JOINT_ID},
{"GearJoint", PHYSICS_GEAR_JOINT_ID},
{"FrictionJoint", PHYSICS_FRICTION_JOINT_ID},
{"WeldJoint", PHYSICS_WELD_JOINT_ID},
{"RopeJoint", PHYSICS_ROPE_JOINT_ID},
{"WheelJoint", PHYSICS_WHEEL_JOINT_ID},
{"MotorJoint", PHYSICS_MOTOR_JOINT_ID},
// Thread
{"Thread", THREAD_THREAD_ID},
{"Channel", THREAD_CHANNEL_ID},
// The modules themselves. Only add abstracted modules here.
{"filesystem", MODULE_FILESYSTEM_ID},
{"graphics", MODULE_GRAPHICS_ID},
{"image", MODULE_IMAGE_ID},
{"sound", MODULE_SOUND_ID},
};
StringMap<Type, TYPE_MAX_ENUM> types(typeEntries, sizeof(typeEntries));
static_assert((sizeof(typeEntries) / sizeof(typeEntries[0])) == TYPE_MAX_ENUM, "Type name array size doesn't match the total number of type IDs!");
bool getType(const char *in, love::Type &out)
bool getTypeName(const char *in, love::Type &out)
{
return types.find(in, out);
}
bool getType(love::Type in, const char *&out)
bool getTypeName(love::Type in, const char *&out)
{
return types.find(in, out);
}
+3 -2
View File
@@ -123,8 +123,9 @@ typedef std::bitset<TYPE_MAX_ENUM> TypeBits;
**/
extern const TypeBits *typeFlags;
bool getType(const char *in, Type &out);
bool getType(Type in, const char *&out);
void addTypeName(Type type, const char *name);
bool getTypeName(const char *in, Type &out);
bool getTypeName(Type in, const char *&out);
} // love
+1 -1
View File
@@ -59,7 +59,7 @@ const luaL_Reg w_Data_functions[] =
int w_Data_open(lua_State *L)
{
luax_register_type(L, DATA_ID, w_Data_functions);
luax_register_type(L, DATA_ID, "Data", w_Data_functions, nullptr);
return 0;
}
+1 -3
View File
@@ -29,10 +29,8 @@ namespace love
{
Data *luax_checkdata(lua_State *L, int idx);
int w_Data_getString(lua_State *L);
int w_Data_getPointer(lua_State *L);
int w_Data_getSize(lua_State *L);
int w_Data_open(lua_State *L);
extern const luaL_Reg w_Data_functions[];
} // love