I'm using type_of() in a weird way. Is this supposed to compile?

Um, so I started experimenting with workarounds for methods and ended up getting something like this. Is this supposed to compile? It even runs and does what I want it to. Will this get patched out now that I’ve mentioned it? nonononono-

package gpu

import "core:log"
import "core:mem"
import sdl "vendor:sdl3"

check_ptr :: proc(ptr: rawptr, loc := #caller_location) -> bool {
	if ptr == nil {
		log.error(sdl.GetError(), location = loc)
	}
	return ptr != nil
}

device: ^sdl.GPUDevice

TB :: ^Transfer_Buffer
Transfer_Buffer :: struct {
	using _tbv: ^Transfer_Buffer_Vtable,
	tb:         ^sdl.GPUTransferBuffer,
}

Transfer_Buffer_Vtable :: struct {
	Create:  type_of(tb_create),
	Map:     type_of(tb_map),
	Unmap:   type_of(tb_unmap),
	Release: type_of(tb_release),
}

tbv := Transfer_Buffer_Vtable{tb_create, tb_map, tb_unmap, tb_release}

make_transfer_buffer :: proc() -> Transfer_Buffer {
	return {_tbv = &tbv}
}

tb_create :: proc(self: TB, size: u32, download := false) -> bool {
	self.tb = sdl.CreateGPUTransferBuffer(
		device,
		{size = size, usage = .DOWNLOAD if download else .UPLOAD},
	)
	return check_ptr(self.tb)
}

tb_map :: proc(self: TB, cycle := false) -> rawptr {
	return sdl.MapGPUTransferBuffer(device, self.tb, cycle)
}

tb_unmap :: proc(self: TB) {
	sdl.UnmapGPUTransferBuffer(device, self.tb)
}

tb_release :: proc(self: TB) {
	sdl.ReleaseGPUTransferBuffer(device, self.tb)
}

tb_example :: proc() {
	tb := make_transfer_buffer()
	tb->Create(mem.Megabyte); defer tb->Release()
	{
		ptr := tb->Map(); defer tb->Unmap()
		// put stuff in buffer
	}
	// upload to gpu buffers/textures
}
1 Like

This does work, but I’d also not do this. And please don’t try to emulate OOP in Odin. What you are doing is a bad idea.

Yeah, I probably won’t. Just was curious about it.