From 3b6f37dd2c336987251d53a4678396ef38921b3e Mon Sep 17 00:00:00 2001
From: Mike Pall
+The following code explains how to define metamethods for a C type. +We define a simple point type and add some operations to it: +
++ +① + + + +② + +③ + +④ + + + +⑤ + +⑥local ffi = require("ffi") +ffi.cdef[[ +typedef struct { double x, y; } point_t; +]] + +local point +local mt = { + __add = function(a, b) return point(a.x+b.x, a.y+b.y) end, + __len = function(a) return math.sqrt(a.x*a.x + a.y*a.y) end, + __index = { + area = function(a) return a.x*a.x + a.y*a.y end, + }, +} +point = ffi.metatype("point_t", mt) + +local a = point(3, 4) +print(a.x, a.y) --> 3 4 +print(#a) --> 5 +print(a:area()) --> 25 +local b = a + point(0.5, 8) +print(#b) --> 12.5 ++
+Here's the step-by-step explanation: +
++① This defines the C type for a +two-dimensional point object. +
++② We have to declare the variable +holding the point constructor first, because it's used inside of a +metamethod. +
++③ Let's define an __add +metamethod which adds the coordinates of two points and creates a new +point object. For simplicity, this function assumes that both arguments +are points. But it could be any mix of objects, if at least one operand +is of the required type (e.g. adding a point plus a number or vice +versa). Our __len metamethod returns the distance of a point to +the origin. +
++④ If we run out of operators, we can +define named methods, too. Here the __index table defines an +area function. For custom indexing needs, one might want to +define __index and __newindex functions instead. +
++⑤ This associates the metamethods with +our C type. This only needs to be done once. For convenience, a +constructor is returned by +ffi.metatype(). +We're not required to use it, though. The original C type can still +be used e.g. to create an array of points. The metamethods automatically +apply to any and all uses of this type. +
++Please note that the association with a metatable is permanent and +the metatable must not be modified afterwards! Ditto for the +__index table. +
++⑥ Here are some simple usage examples +for the point type and their expected results. The pre-defined +operations (such as a.x) can be freely mixed with the newly +defined metamethods. Note that area is a method and must be +called with the Lua syntax for methods: a:area(), not +a.area(). +
+Here's a list of common C idioms and their translation to the -- cgit v1.2.3-55-g6feb