Skip to content

Instantly share code, notes, and snippets.

@Clemapfel
Last active September 11, 2022 18:29
Show Gist options
  • Save Clemapfel/31c1c5bb485c27c9e646f2f7cf41cf57 to your computer and use it in GitHub Desktop.
Save Clemapfel/31c1c5bb485c27c9e646f2f7cf41cf57 to your computer and use it in GitHub Desktop.
Swizzling in Julia: Basic Mechanism
# Basic mechanism for how to implement GLSL-like swizzling in Julia
mutable struct Vec2
_private_00::Float32
_private_01::Float32
Vec2(x, y) = new(x, y)
end
function Base.getproperty(instance::Vec2, sym::Symbol)
# within this function we still somehow need to get the values of instances field. Using regular Julia syntax `.`
# would cause a stackoverflow error as `.` calls `getproperty` which is this function
# instead, we use the Julia C-Library to access the values
# at that point we simply need to parse the `sym` argument and return the correct value permutation
# this function is currently not type stable but with some more effort I feel like this is doable for
# all the glm vectors types without sacrificing performance at all
if sym == :_private_00 || sym == :_private_00
# prevent users from messing with actual values
throw(ErrorException("type " * string(Vec2) * " has no field " * string(sym)))
else
x_ptr = ccall(:jl_get_nth_field, Ptr{Cvoid}, (Ptr{Cvoid}, Cint), pointer_from_objref(instance), 0)
y_ptr = ccall(:jl_get_nth_field, Ptr{Cvoid}, (Ptr{Cvoid}, Cint), pointer_from_objref(instance), 1)
x = ccall(:jl_unbox_float32, Float32, (Ptr{Cvoid},), x_ptr)
y = ccall(:jl_unbox_float32, Float32, (Ptr{Cvoid},), y_ptr)
if sym == :x return x
elseif sym == :y return y
elseif sym == :xy return Vec2(x, y)
elseif sym == :yx return Vec2(y, x)
elseif sym == :xx return Vec2(x, x)
elseif sym == :yy return Vec2(y, y)
else
# simulate the regular behavior of a non-overloaded Base.getproperty
throw(ErrorException("type " * string(Vec2) * " has no field " * string(sym)))
end
end
end
# usage
test = Vec2(1, 123)
println(test.yx)
# prints Vec2(123.0f0, 1.0f0)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment