On Saturday, 10 August 2024 at 07:46:46 UTC, Vitaliy Fadeev wrote:
## Trouble 1
Pass the structure through registers ?
## Trouble 2
Wrap the registries in a structure ?
## Use case
I need to pass different events: `Draw_Event`,
`Mouse_Move_Event`, `...`
I need to pass an event to many objects: `foreach (o; world)
o.event (e);`
I need speed.
I want to pass the structure in registers: (like __fastcall
callin convention): `void _event (REG r1, REG r2, REG r3, REG
r4);`. But it's hard to read.
I want comfortable use: (like a wrap registers in struct):
```
void
event (Event e) {
writeln (e.type);
writeln (e.code);
writeln (e.value);
switch (e.type) {
case Type.REL: _rel_event (e); break;
case Type.GUI: _gui_event (e); break;
case Type.APP: _app_event (e); break;
default:
}
}
```
The problem is that the size of the structure is larger than
the size of the register.
```
struct
Event { // 64 bit
ushort type; // 16 bit
ushort code; // 16 bit
uint value; // 32 bit
}
```
But the event size can be > 64 bit. More than register size.
```
struct
Mouse_Event { // 128 bit
ushort type; // 16 bit
ushort code; // 16 bit
uint value; // 32 bit
float x; // 32 bit
float y; // 32 bit
}
struct
Draw_Event { // 192 bit
ushort type; // 16 bit
ushort code; // 16 bit
uint value; // 32 bit
float x; // 32 bit
float y; // 32 bit
float w; // 32 bit
float h; // 32 bit
}
```
How to implement on D?
This depends on the calling convention used by your compiler and
on your CPU architecture. 64 bits is already 2 data registers on
a 32-bit CPU. There are also many calling conventions that allow
multiple data registers to be used when passing structs around.
Do you really need to avoid them being passed on the stack
though? Is your application highly performance critical? (i.e.
kernel code) You could also use `ref const` to avoid the copying,
but your data will probably always be on the stack that way.