Skip to main content


Wrapper used to add binding, change listener, thread safety and animation capabilities to a value. It is used for all component properties.

For a guide on how to use it, see Data binding and properties.

DataWrapper is a generic struct, which means you need to put the type T of your data in DataWrapper(T).

Then you can use DataWrapper.of in order to get a data wrapper for the given value.

With an u64 this would look like:

var property = DataWrapper(u64).of(123);


Note that Self refers to DataWrapper(T)


fn animate(self: *Self, easing: Easing, target: T, duration: u64) void

Easing is equivalent to *const fn(f64) f64 (a function that takes a f64 and returns a f64).

This function starts an animation on the DataWrapper's value from the current value to target and lasting duration milliseconds.

Capy has a few preset easings:


fn hasAnimation(self: *Self) bool

Returns true if the DataWrapper is currently in an animation.
On the other hand it returns false if the animation ended or if there has been no animation.


fn addChangeListener(self: *Self, listener: ChangeListener) !usize

ChangeListener is defined to be

pub const ChangeListener = struct {
function: *const fn (newValue: T, userdata: usize) void,
userdata: usize = 0

The function is called with userdata every time the value of the DataWrapper changes.


fn bind(self: *Self, other: *Self) void

Binds both data wrappers both ways. This means that self and other will always have the same value.


fn bindOneWay(sender: *Self, receiver: *Self) void

Binds receiver to sender. Which means that when sender changes, receiver is set to the new value, but when receiver changes, sender is not set to this new value.


fn get(self: *Self) T

Returns the current value.


fn set(self: *Self, value: T) void

Set the current value to value. This will:

  • clear the current animation, if any
  • call all the change listeners
  • update all data wrappers that are bound to it


fn dependOn(self: *Self, tuple: anytype, function: anytype) !void

This makes the value of this data wrapper entirely dependent on the given parameters, it can only be reverted by calling set()

tuple must be a tuple with pointers to data wrappers

function must be a function accepting as arguments the value types of the data wrappers and returning a new value.

For example:

var a = DataWrapper(u64).of(1);
var b = DataWrapper([]const u8).of("Hello");

var c = DataWrapper(u64).of(undefined);
c.dependOn(.{ a, b }, cFunction);
// now c is equal to 6 because 1 + 5 = 6

fn cFunction(a: u64, b: []const u8) u64 {
return a + b.len;

// now c is equal to 10
// and now c is equal to 7


fn deinit(self: *Self) void

Deallocates all resources previously allocated by this DataWrapper.

Must be called when its lifetime ends.