Conversion between love objects and FFI structures (日本語)

このページでは LÖVE オブジェクトと FFI (Foreign Function Interface : 外部関数インタフェース) 構造体における相互変換法に関して詳述します。

Lua における LÖVE オブジェクトは常にオブジェクト自身を有する userdata オブジェクト (代理) および型識別子により記憶されています。詳細は後述のコードを参照してください。


O.png 何人たりとも使用は非推奨です。それは予告なく仕様変更されることがあります。 LÖVE オブジェクトおよび FFI データ間において仕様変更されない変換は Data:getPointer によるものだけであり、それにより ffi.cast により FFI ポインタへキャストできます。ガーベジ・コレクターは必要があれば、いつでもオリジナルの userdata を消去します。  

O.png 警告します。これは version 0.10.0 のみ該当します。将来のバージョンでは予告なく仕様変更されることがあります。  

関数

この関数は LÖVE オブジェクトを FFI cdata オブジェクトへ変換します。それは型と型名から成るオブジェクト自身 (代理オブジェクトではない) を返します。

概要

Pointer, Type, TypeEnum = objectToPointer( Object )

引数

Object Object
LÖVE オブジェクト

返値

cdata Pointer
オブジェクトの記憶位置を有する FFI ポインタ。
string Type
LÖVE オブジェクトの型。
number TypeEnum
LÖVE オブジェクトの型による列挙値。

関数

この関数は FFI cdata オブジェクトを代理 userdata オブジェクトへ変換を行いますが、 userdata (ユーザデータ) オブジェクトへの metatable (メタテーブル) と代理オブジェクトに対しては型 ID を代入するために型名の指定は必要です。

概要

Object = pointerToObject( Pointer, Type, TypeEnum )

引数

cdata Pointer
オブジェクトの記憶位置を有する FFI ポインタ。
string Type
LÖVE オブジェクトの型。
number TypeEnum
LÖVE オブジェクトの型による列挙値。

返値

Object Object
LÖVE オブジェクト

コード

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,
 
        // モジュール自身。こちらには、抽象化されたモジュールのみ追加してください。
        MODULE_FILESYSTEM_ID,
        MODULE_GRAPHICS_ID,
        MODULE_IMAGE_ID,
        MODULE_SOUND_ID,
 
        // 必要なビット数を計算します。
        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

そのほかの言語