|
3 | 3 |
|
4 | 4 | This document is meant to clearly show the principles on which archetype works without you having to decipher the macro heavy archetype.h file. The intention is to show how the principles have been combined, and provide a rationale for why I have implemented archetype this way. |
5 | 5 |
|
6 | | -Underneath the hood Archetype uses manual vtables to acheive type erasure and run time polymorphism. This is not dissimilar from how virtual functions in traditional inheritance work. Vtables and surrounding infrastructure require a lot of boiler plate. The point of Archetype is to automate manual vtable generation, in a modular/composable way. |
| 6 | +Underneath the hood `Archetype` uses manual vtables to acheive type erasure and run time polymorphism. This is not dissimilar from how virtual functions in traditional inheritance work. Vtables and surrounding infrastructure require a lot of boiler plate. The point of `Archetype` is to automate manual `vtable` generation, in a modular/composable way. |
| 7 | + |
| 8 | +### The basic vtable |
| 9 | +A `vtable` is a structure containing free function pointers (non member function pointers). For example, this is a `vtable` structure containing function pointers for `func_a` and `func_b`. |
| 10 | + |
| 11 | +```cpp |
| 12 | +struct vtable |
| 13 | +{ |
| 14 | + int (*func_a)(int); |
| 15 | + float (*func_b)(float); |
| 16 | +}; |
| 17 | +``` |
| 18 | +We can now assign any function that matches this signature to the vtable. For example: |
| 19 | +
|
| 20 | +```cpp |
| 21 | +int func_a(int a) { return a + 5; } |
| 22 | +float func_b(float b) { return b + 5.3; } |
| 23 | +
|
| 24 | +vtable mytable; |
| 25 | +mytable.func_a = &func_a; |
| 26 | +mytable.func_b = &func_b; |
| 27 | +``` |
| 28 | +we can now call these functions through the vtable: |
| 29 | +```cpp |
| 30 | +mytable.func_a(5); //returns 10; |
| 31 | +mytable.func_b(5.f); //returns 10.3; |
| 32 | +``` |
| 33 | +### The object facing vtable |
| 34 | +In Archetype the goal is binding objects/classes, not free functions. Member function pointers (non static) are not free functions. They have to point to both the correct function, and the object instance, which mean they don't have the size of a free function pointer. |
| 35 | + |
| 36 | +Lets say we want a vtable that can call objects of the following type: |
| 37 | +```cpp |
| 38 | +struct A |
| 39 | +{ |
| 40 | + int func_a(int a) { return a + internal_int++; } |
| 41 | + float func_b(float b) { return b + (internal_float += 1.3f); } |
| 42 | + int internal_int = 5; |
| 43 | + int internal_float = 5.3; |
| 44 | +}; |
| 45 | +``` |
| 46 | + |
| 47 | +We can get around this by storing free functions that can be called with an object pointer. For example our vtable becomes: |
| 48 | + |
| 49 | +```cpp |
| 50 | +struct vtable |
| 51 | +{ |
| 52 | + int (*func_a)(A *, int); |
| 53 | + float (*func_b)(A *, float); |
| 54 | +}; |
| 55 | +``` |
| 56 | +We can then assign this vtable to call an object of type `A's` functions. |
| 57 | +```cpp |
| 58 | +A obj; |
| 59 | +vtable vtbl; |
| 60 | +vtbl.func_a = [](A * ptr, int a) { return ptr->func_a(a); }; |
| 61 | +vtbl.func_b = [](A * ptr, float b) { return ptr->func_b(b); }; |
| 62 | +
|
| 63 | +vtbl.func_a(obj, 5); // call func_a on obj |
| 64 | +vtbl.func_b(obj, 6.4); // call func_b on obj |
| 65 | +``` |
| 66 | + |
| 67 | +This implementation is not very generic. As our vtable depends on type A. We can make the vtable type agnostic by passing in the object as a void pointer instead. We can push the type specific handling into the lambda. |
| 68 | + |
| 69 | +```cpp |
| 70 | +struct vtable |
| 71 | +{ |
| 72 | + int (*func_a)(void *, int); |
| 73 | + float (*func_b)(void *, float); |
| 74 | +}; |
| 75 | + |
| 76 | +vtbl.func_a = [](void * ptr, int a) { |
| 77 | + return static_cast<A*>(ptr)->func_a(a); |
| 78 | +}; |
| 79 | + |
| 80 | +vtbl.func_a(static_cast<void*>(obj), 5); |
| 81 | +``` |
| 82 | +
|
| 83 | +### The view |
| 84 | +
|
| 85 | +
|
| 86 | +
|
| 87 | +
|
| 88 | +
|
| 89 | +
|
| 90 | +
|
7 | 91 |
|
8 | 92 |
|
9 | 93 | ```cpp |
|
0 commit comments