|
|
(4 intermediate revisions by 3 users not shown) |
Line 1: |
Line 1: |
− | {{notice|This is '''NOT''' recommended for ''anyone'' to use. It will break at any time. The only non-breaking conversion between love objects and FFI data is via [[Data:getPointer]], which you can cast to a FFI pointer via ffi.cast. The garbage collector may erase the original userdata at any time.}}
| |
| | | |
− | This page details how to convert between löve objects and [http://luajit.org/ext_ffi.html FFI] (Foreign Function Interface) structures.
| |
− |
| |
− | Love objects in lua are always stored in a userdata object (Proxy) that contains the object itself, and a type identifier. See the code below for details.
| |
− |
| |
− | == Function ==
| |
− | This function converts a love object into a FFI cdata object. It returns the object itself (not the Proxy object), it's type and type name.
| |
− | === Synopsis ===
| |
− | <source lang="lua">
| |
− | Pointer, Type, TypeEnum = objectToPointer( Object )
| |
− | </source>
| |
− | === Arguments ===
| |
− | {{param|Object|Object|A LÖVE object.}}
| |
− | === Returns ===
| |
− | {{param|cdata|Pointer|An FFI pointer containing the object's location.}}
| |
− | {{param|string|Type|The LÖVE object's type.}}
| |
− | {{param|number|TypeEnum|The LÖVE object's type as an enumeration value.}}
| |
− |
| |
− | == Function ==
| |
− | This function converts a FFI cdata object into a Proxy userdata object, it is required to give the type name to assign the metatable to the userdata object, and the type id for the Proxy object.
| |
− |
| |
− | === Synopsis ===
| |
− | <source lang="lua">
| |
− | Object = pointerToObject( Pointer, Type, TypeEnum )
| |
− | </source>
| |
− | === Arguments ===
| |
− | {{param|cdata|Pointer|An FFI pointer containing the object's location.}}
| |
− | {{param|string|Type|The LÖVE object's type.}}
| |
− | {{param|number|TypeEnum|The LÖVE object's type as an enumeration value.}}
| |
− | === Returns ===
| |
− | {{param|Object|Object|A LÖVE object.}}
| |
− |
| |
− | == Code ==
| |
− | '''<source lang="lua">
| |
− | ffi = require("ffi")
| |
− |
| |
− | ffi.cdef [[
| |
− | typedef enum {
| |
− | INVALID_ID = 0,
| |
− | 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,
| |
− |
| |
− | // Audio
| |
− | AUDIO_SOURCE_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
| |
− | } Type;
| |
− |
| |
− | typedef struct Object {
| |
− | } Object;
| |
− |
| |
− | typedef struct Proxy {
| |
− | Type type;
| |
− | Object * object;
| |
− | };
| |
− | ]]
| |
− |
| |
− | local conv = {}
| |
− |
| |
− | function conv.objectToPointer(Object)
| |
− | local Proxy = ffi.cast("Proxy *", Object)
| |
− | return Proxy.object, tonumber(Proxy.type), Object:type()
| |
− | end
| |
− |
| |
− | function conv.pointerToObject(CData, Type, TypeName)
| |
− | local Object = newproxy(true)
| |
− | local Metatable = debug.getregistry()[TypeName]
| |
− | debug.setmetatable(Object, Metatable)
| |
− |
| |
− | local Proxy = ffi.cast("Proxy *", Object)
| |
− | Proxy.type = Type
| |
− | Proxy.object = CData
| |
− |
| |
− | return Object
| |
− | end
| |
− |
| |
− | return conv
| |
− | '''
| |