To make sure the messages in my message-queue are type-safe, I have to record
the message type in each message.
This is how I went about it:
proc idOfType*(T: typedesc): MsgTypeID {.inline.} =
let tid = 0 # Accesses "type register here" ...
MsgTypeID(tid)
proc sendMsg*[T](q: QueueID, m: ptr Msg[T]): void {.inline.} =
let typeidOfT {.global.} = idOfType(T)
m.mybase.mytypeid = typeidOfT
fillAndSendMsg[T](q, m, true)
It looked like it worked, but then today I realised I was using a single type
in the test messages, so I added a second type to my test, and then it failed.
To get it to work again, I have to change the code to this:
proc idOfType*(T: typedesc): MsgTypeID {.inline.} =
let tid = 0 # Accesses "type register here" ...
MsgTypeID(tid)
proc sendMsg*[T](q: QueueID, m: ptr Msg[T]): void {.inline.} =
let typeidOfT = idOfType(T)
m.mybase.mytypeid = typeidOfT
fillAndSendMsg[T](q, m, true)
I was under the impressing that since sendMsg() is generic, the compiler would
generate one typeidOfT _per type T_. Since my test is now failing with two
types, I assume the compiler generates a single typeidOfT for all sendMsg()
"instantiations".
Is there a way to work around that? It's rather expensive to compute the ID of
a type (it involves locks and creating shared heap objects), so I don't want to
do that for each message, but rather only once for each type.
I've also tried the following, which doesn't compile:
proc sendMsg*[T](q: QueueID, m: ptr Msg[T]): void {.inline.} =
static:
let typeidOfT {.global.} = idOfType(T)
m.mybase.mytypeid = typeidOfT
fillAndSendMsg[T](q, m, true)
proc sendMsg*[T](q: QueueID, m: ptr Msg[T]): void {.inline.} =
static:
const typeidOfT {.global.} = idOfType(T)
m.mybase.mytypeid = typeidOfT
fillAndSendMsg[T](q, m, true)