mirror of
https://github.com/love2d/love.git
synced 2026-08-16 00:02:12 +02:00
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:
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
Reference in New Issue
Block a user