Here is simplified code reproduces same runtime error. This code cause SIGSEGV
because it reads an address of `cb`, and stores it to `gpointer`. Using
`unsafeAddr` without understanding pointer and address is as dangerous as going
to grocery without wearing mask in pandemic.
import
Just following the conversation. it'd be nice if you post what you finally end
up with.
No need for me but maybe others can give a fix / suggestion
I've patched it a little, to use const hashes and copy the api I previously
had. Can post it later if you like, even if its slower I still consider useing
it.
IDK, You may encounter bugs if you make a class hierarchy from EventBase as
@jyapayne said but I dont think it would be 2x slower if you change it as
yours. I mean, I was lazy and used type name as keys instead of hash and used
sequence as container for events. That must be the reason, I guess
Not only this, but its also quite slow I've benchmarked @sky_khan s system (I
like it) but it's twice as slow than mine with pointers
@sky_khan, your solution seems to work too, although I don't completely trust
Nim's inheritance due to past issues. Maybe those are ironed out now though
Ah, I misunderstood what you were trying to do. @Hlaaftana is correct, in order
for type safety to remain, Nim needs to know what types you want to include in
the event registry at compile time. I took a very brief stab at a rough version
using macros (that can certainly be improved), and here's
The solution here is to generate an object from a list of event types which
generates a seq of procs field for each type, then generate a proc for
dispatching each event type based on its field. It requires the registry type
to know about all the event types beforehand. Otherwise there is no way
Not sure if this is the best way but this seems working:
import tables, typetraits
type
EventBase = object of RootObj
EventProc = proc(ev:EventBase) {.nimcall.}
EventCallback[T:EventBase] = proc(ev:T) {.nimcall.}
EventReg = object
This can unfortunately just bind one event type. That's the reason i used
pointers in the first place. But i like the macros.
@enthus1ast, why not something using Nim's generics? Is there a reason you
wanted to use pointers?
For example, you could do something like this (made a little better with
macros):
import tables
import macros
type
Callback[T] = proc (arg: T)
Signal[T] = ref
@planetis
> At least in my experience I used simple empty components as 'Tags' that
> notify the next system of changes. They can be added and removed very
> efficiently.
In general, I agree with this. In many cases using components as "events" works
better than explicit events because they ca
A good event system would be great to have, though in the past I found it hard
to debug. Recently I've been looking into Dart (for Flutter actually), and
perhaps what you need is state management. A nice approach to decouple code I
saw there was the BloC pattern. here is an example to see how it
Imho events in an ecs are an essential building block for real decoupling.
Without them the systems are intertwined.
Eg.:
An entity receives damage. Without an event system the inflictDamage proc must
call eg the playDamageSound or the createBlood proc etc. Therefore the
inflictDamage proc mus
How about not using events with ECS. I mean there is nothing stopping you, but
event driven programing is more related to OOP. At least in my experience I
used simple empty components as 'Tags' that notify the next system of changes.
They can be added and removed very efficiently. Of course you
one thing that seems to work is to use `system.rawProc`
proc connect2[E](reg: Reg, cb: proc (ev: E)) =
const typehash = hash($E)
if not reg.ev.hasKey(typehash):
reg.ev[typehash] = initHashSet[pointer]()
reg.ev[typehash].incl rawProc cb
Run
I'm trying to write a simple event system (for use in my ECS and game).
I want to be able to connect and disconnect events at runtime.
This is what i have so far:
import tables, sets, hashes
type
Reg = ref object
ev: Table[Hash, HashSet[pointer]]
18 matches
Mail list logo