1
1
mirror of https://github.com/NixOS/mobile-nixos.git synced 2024-12-18 05:21:47 +03:00
mobile-nixos/boot/lib/lvgui/fiddlier.rb
2021-01-01 21:37:29 -05:00

101 lines
2.6 KiB
Ruby

# This module augments Fiddle with useful helpers.
module LVGL
end
module LVGL::Fiddlier
# Given a +type+, returns the value of the global +name+.
def get_global!(type, name)
addr = handler.sym(name)
raise(Fiddle::DLError, "cannot find symbol #{name}") unless addr
s = struct(["#{type} value"])
s.new(addr).value
end
# Given a +type+, sets the global +name+ to +new_value+.
def set_global!(type, name, new_value)
addr = handler.sym(name)
raise(Fiddle::DLError, "cannot find symbol #{name}") unless addr
s = struct(["#{type} value"])
tmp = s.new(addr)
tmp.value = new_value
tmp.value
end
def get_global_struct!(struct, name)
addr = handler.sym(name)
raise(Fiddle::DLError, "cannot find symbol for struct #{name}") unless addr
struct.new(addr)
end
# Using +set_global!+ and +get_global!+, creates accessors for a global
# variable.
def global!(type, name)
method_name = name.to_sym
define_method(method_name) do
get_global!(type, name)
end
module_function method_name
method_name = "#{name}=".to_sym
define_method(method_name) do |value|
set_global!(type, name, value)
end
module_function method_name
end
# TODO: parse `typedef enum {...} name;`
def enum!(name, values, type: "int")
typedef name.to_s, type.to_s
mod = self.const_set(name.to_sym, Module.new)
current_value = 0
values.each do |data|
if data.is_a? Hash
name = data.keys.first.to_sym
current_value = data.values.first
else
name = data.to_sym
end
mod.const_set(name, current_value)
current_value += 1
end
end
# Flattens the given nested struct
def flatten_struct!(fields, prefix: nil)
fields.map do |field|
type = field.first
name = [prefix, field.last].compact.join("_")
if type.is_a? Array then
flatten_struct!(type, prefix: name)
else
[[type.to_sym, name.to_sym]]
end
end.flatten(1)
end
# Parses nested structs into a flattened Fiddle struct.
# XXX: broken because of struct alignment padding / packing
# -> http://www.catb.org/esr/structure-packing/#_padding
def struct!(fields)
flattened = flatten_struct!(fields).map do |field|
type = field.first
name = field.last
"#{type} #{name}"
end
struct(flattened)
end
# Define the given +sym+ as a function.
# It will auto-wrap the method using a closure.
def bound_method!(sym, sig)
sym = sym.to_sym
module_function sym
ctx = self
@func_map[sym.to_s] = bind(sig) do |*args|
ctx.send(sym, *args)
end
end
end