Difference between revisions of "Conversion between love objects and FFI structures"

(Meant no malice with my last commit, accidentally left in the minor edit flag. This'll be a major edit to compensate.)
(Blanked page - it's broken and a fundamentally broken approach. It was misleading people.)
 
(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
 
'''
 

Latest revision as of 04:12, 2 February 2020