-
-
Save exelotl/09c7fb07ae08d97aa9738d63b960bacc to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Each Actor object has a pointer an 'implementation' object (i.e. a vtable) containing methods such as create, update, draw, etc. | |
# The methods are free to do whatever they want with the 'data' in the actor, depending on what kind of actor it is (by casting the data to some relevant object type) | |
# Actor[T] is used to provide some safety and convenience when dealing with an Actor of a known kind (though T is not used anywhere in the type definition). | |
# Why am I doing this? | |
# Well this game is for an embedded platform (GBA) and I need a 'mixed bag' of objects of different kinds. | |
# I'd like to stay clear of malloc, allocating everything statically is hugely beneficial to me. | |
# Nim methods in their current state don't quite cut it for me (dispatch trees + too many hidden fields from RootObj) | |
const ActorDataSize = 64 | |
type | |
Actor*[T] = ptr ActorObj | |
ActorObj* = object | |
impl*: ptr ActorImpl ## vtable pointer | |
dataBytes: array[ActorDataSize, byte] ## pointer to any kind of data | |
ActorMethod* = proc (actor:pointer) {.nimcall.} | |
ActorImpl* = object | |
create*: ActorMethod | |
destroy*: ActorMethod | |
update*: ActorMethod | |
draw*: ActorMethod | |
template data*[T](actor:Actor[T]): ptr T = | |
## Retrieve the data from an actor of a known kind | |
cast[ptr T](addr actor.dataBytes) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment