Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Nim - Create sequence of objects which implement a method

I want to program a game and would like to use a component pattern for multiple entities.

In a language with interfaces / type-classes / multiple inheritance there would be no problem.

I want some entities to be updateable but not renderable and some shall be both.


Haskell:

class Updateable a where
    update :: Float -> a -> a

class Renderable a where
    render :: a -> Picture

class InputHandler a where
    handleInput :: Event -> a -> a

I can create a list of things that can be updated.

updateAll :: Updateable a => Float -> [a] -> [a]
updateAll delta objs = map (update delta) objs

In Java/D/... this could be implemented via Interfaces

interface Updateable {
    void update(float delta);
}

// somewhere in a method
List<Updateable> objs = ...;
for (Updateable o : objs) {
    o.update(delta);
}

Now I am wondering how this can be implemented in nim with multimethods.

Can the existence of a fitting multimethod be expressed in a type?

var objs: seq[???] = @[]



Edit: Added more code and fixed incorrect Haskell example
like image 287
Karroffel Avatar asked Mar 12 '23 20:03

Karroffel


1 Answers

I'm not sure if this answers your question, but it's worth mentioning.

If you were to store you game objects in separate lists based on type, you could still write a lot of generic logic. Storing objects by type has better better performance because of read-ahead and branch prediction. See this lecture, from a guy who should know what he's talking about: Multiprocessor Game Loops: Lessons from Uncharted 2: Among Thieves.

For instance, if you have defined a texture proc for some of your object types, then you can write a generic draw(t: T) = magicRenderToScreen(texture(t)) proc that will work for all of them. This is also useful if you are implementing resource pools, or any kind of general behaviour really.

You do have to include each affected object type in the render and update loops somehow, but that's usually not a big deal in practice. You can even use a simple macro to make this less verbose, so your render loop simply contains something like renderAll(players, enemies, sprites, tiles)

Generic lists are not straightforward in compiled languages, and nim forces you to see it, which is kind of good when you're working on a game. To have generic lists you typically either have to use pointers and dynamic dispatch, or some kind of union type. I seem to remember that nim used to be able to dispatch to the correct multi-methods from parent object ref's, (which would enable lists to contain several types and dispatch dynamically at runtime) but I'm honestly not sure if that can still be done...?

Someone more knowledgeable please let us know!

like image 50
Jostein Avatar answered Mar 15 '23 08:03

Jostein