On 17.09.23 17:05, Vitaliy Fadeev wrote:
Hi!
I want to change a method ```Draw``` on a custom object when the ```MouseIn``` event occurs.
This is known as "Change State" of the object: ```Init``` -> ```Hovered```.

I want to change the state of an object by changing its class, like this:

```d

this.__vptr = typeid(CLS).vtbl.ptr;

```

I have read the ABI and am confident in replacing ```__vptr``` as long as the classes contain the same fields and the same interfaces.

Example:
```d
// O
//   to!state
// State_Init    : O
//   Draw
// State_Hovered : O
//   Draw
//
// o.to!State_Hovered
// o.to!State_Init

class O
{
   void to(CLS)()
   {
     // if (same fields && same interfaces && same instance size)
     this.__vptr =
       cast(immutable(void*)*)typeid(CLS).vtbl.ptr;
   }
}

State_Init : O
   void Draw() { /* ... */ }

State_Hovered : O
   void Draw() { /* ... */ }
```

when MouseIn:

```d
   ...
   o.to!State_Hovered();
   ...
```

when MouseOut:
```d
   ...
   o.to!State_Init();
   ...
```

It works! But I want to ask how to make this 100% the best of the best?
What should I consider before changing ```__vptr``` ?

You could model it oop style like this:
https://run.dlang.io/is/MJb5Fk
This solution might not be to your taste, as it involves interfaces, and classes and objects and garbage (all the news) ...

another option could be to model your own VTable in a struct like this:
https://run.dlang.io/is/3LTjP5

Kind regards,
Christian

Reply via email to