Re: change object class
On 23.09.23 05:11, Vitaliy Fadeev wrote: On Friday, 22 September 2023 at 19:50:17 UTC, Christian Köstlin wrote: another option could be to model your own VTable in a struct like this: https://run.dlang.io/is/3LTjP5 Kind regards, Christian Thank, Christian ! True nice tasty solution with ```VTable```! And further... the project is growing. ``` void Draw() { DrawBG(); DrawFG(); } ``` And we want use ```DrawBG()``` code from ```initial``` in other states, like ```Selected```. How to use some functions from ```initial``` via ```VTable``` ? I see solution in ```classes``` and methods with ```override``` keyword. ```VTable``` does the same thing as ```__vptr``` ? VTable is your structure .. it does exactly what you want it to do. __vptr is the internal implementation of virtual methods in the dlang object model. Line 20 and 21 in my example initialize the two `VTable`s Initial and Hovered. You can change VTable to contain two function pointers and initialize those as you like for the instances of the VTable structs. e.g. ```d struct DrawVTable { void function(Chip, Renderer) background; void function(Chip, Renderer) foreground; } // define functions to draw the different fore and backgrounds ... ... VTable initial = VTable(, ); VTable hovered = VTable(, ); VTable selected = VTable(, ); ``` Kind regards, Christian
Re: change object class
On 23.09.23 05:25, Vitaliy Fadeev wrote: On Friday, 22 September 2023 at 19:50:17 UTC, Christian Köstlin wrote: On 17.09.23 17:05, Vitaliy Fadeev wrote: Hi! 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 ```Behavior``` is beautiful code! But it contains a second ```new``` when ```Chip``` is created. One ```new``` is possible? Christian, really nice code! Here a solution with less `new`s: https://run.dlang.io/is/iV1qVq. It really depends on the program that you are doing if creating those news is a problem. Kind regards, Christian
Re: change object class
On Friday, 22 September 2023 at 19:50:17 UTC, Christian Köstlin wrote: On 17.09.23 17:05, Vitaliy Fadeev wrote: Hi! 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 ```Behavior``` is beautiful code! But it contains a second ```new``` when ```Chip``` is created. One ```new``` is possible? Christian, really nice code! Does ```__vptr``` do the same thing ?
Re: change object class
On Friday, 22 September 2023 at 21:37:37 UTC, Imperatorn wrote: On Friday, 22 September 2023 at 14:03:40 UTC, Vitaliy Fadeev wrote: On Friday, 22 September 2023 at 12:53:28 UTC, Imperatorn wrote: You're basically just describing polymorphism. I can post an example tomorrow, it's midnight here now. Thank you. Of course! It's interesting to look at the solutions to choose the best one.
Re: change object class
On Friday, 22 September 2023 at 19:50:17 UTC, Christian Köstlin wrote: another option could be to model your own VTable in a struct like this: https://run.dlang.io/is/3LTjP5 Kind regards, Christian Thank, Christian ! True nice tasty solution with ```VTable```! And further... the project is growing. ``` void Draw() { DrawBG(); DrawFG(); } ``` And we want use ```DrawBG()``` code from ```initial``` in other states, like ```Selected```. How to use some functions from ```initial``` via ```VTable``` ? I see solution in ```classes``` and methods with ```override``` keyword. ```VTable``` does the same thing as ```__vptr``` ?
Re: change object class
On Friday, 22 September 2023 at 14:03:40 UTC, Vitaliy Fadeev wrote: On Friday, 22 September 2023 at 12:53:28 UTC, Imperatorn wrote: On Friday, 22 September 2023 at 03:33:08 UTC, Vitaliy Fadeev wrote: [...] What I mean is, why not use other language constructs like mixins or inheritance with some mapping for example? Can you give an example? You're basically just describing polymorphism. I can post an example tomorrow, it's midnight here now.
Re: change object class
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
Re: change object class
On Friday, 22 September 2023 at 12:53:28 UTC, Imperatorn wrote: On Friday, 22 September 2023 at 03:33:08 UTC, Vitaliy Fadeev wrote: On Friday, 22 September 2023 at 02:51:10 UTC, Vitaliy Fadeev wrote: ... ``` Chip id name Sense() Draw() ``` instance ``` chip = new Chip(); ``` compiled to ``` chip __vtbl -> Chip __monitor Sense() idDraw() name ``` I want ``` chip __vtbl --+ id | name | |-> Chip_Hovered | Sense() | Draw() | +-> Chip_Hovered Sense() Draw() ``` What I mean is, why not use other language constructs like mixins or inheritance with some mapping for example? Can you give an example?
Re: change object class
On Friday, 22 September 2023 at 03:33:08 UTC, Vitaliy Fadeev wrote: On Friday, 22 September 2023 at 02:51:10 UTC, Vitaliy Fadeev wrote: ... ``` Chip id name Sense() Draw() ``` instance ``` chip = new Chip(); ``` compiled to ``` chip __vtbl -> Chip __monitor Sense() idDraw() name ``` I want ``` chip __vtbl --+ id | name | |-> Chip_Hovered | Sense() | Draw() | +-> Chip_Hovered Sense() Draw() ``` What I mean is, why not use other language constructs like mixins or inheritance with some mapping for example?
Re: change object class
On Friday, 22 September 2023 at 03:33:08 UTC, Vitaliy Fadeev wrote: On Friday, 22 September 2023 at 02:51:10 UTC, Vitaliy Fadeev wrote: ... the most correct ``` chip __vtbl ---+ // one of __monitor | id| name | |-> Chip // init | Sense() | Draw() | |-> Chip_Hovered // on mouseover | Sense() | Draw() | +-> Chip_Selected // on mouseclick Sense() Draw() ```
Re: change object class
On Friday, 22 September 2023 at 02:51:10 UTC, Vitaliy Fadeev wrote: ... ``` Chip id name Sense() Draw() ``` instance ``` chip = new Chip(); ``` compiled to ``` chip __vtbl -> Chip __monitor Sense() idDraw() name ``` I want ``` chip __vtbl --+ id | name | |-> Chip_Hovered | Sense() | Draw() | +-> Chip_Hovered Sense() Draw() ```
Re: change object class
On Thursday, 21 September 2023 at 18:19:47 UTC, Imperatorn wrote: On Sunday, 17 September 2023 at 15:05:59 UTC, 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```. [...] Interesting, but why would you want to do it that way? Q & A. You can check the logic. How to increase the battery life of a smartphone? Reducing operations. How to change the state of a button widget, for example, on mouseover? By changing the pointer to the Draw method. In addition to Draw, the widget has a Sense method. How to replace all pointers to methods at once? Replace the pointer with a class. (It's like a change of state! Exactly Turing's State Machine.) The object fields are the same. Behavior changes. The contents of the fields remain in memory. Only the pointer to the method table changes. Of course, this requires care and forethought. Perhaps the risks of changing class can be reduced by performing additional checks. Changing class is a convenient tool. I want to use it.
Re: change object class
On Sunday, 17 September 2023 at 15:05:59 UTC, 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```. [...] Interesting, but why would you want to do it that way?
Re: change object class
On Sunday, 17 September 2023 at 17:10:16 UTC, evilrat wrote: On Sunday, 17 September 2023 at 15:05:59 UTC, Vitaliy Fadeev wrote: It works! But I want to ask how to make this 100% the best of the best? What should I consider before changing ```__vptr``` ? If that works for you with that constraint of having exact memory layout then it should be ok. No, this is Undefined Behavior and will likely cause you trouble in the future (as in: some very hard to debug bugs may appear). Better to store the state in the object and select the behavior using a switch on the state. -Johan
Re: change object class
On Sunday, 17 September 2023 at 15:05:59 UTC, Vitaliy Fadeev wrote: It works! But I want to ask how to make this 100% the best of the best? What should I consider before changing ```__vptr``` ? If that works for you with that constraint of having exact memory layout then it should be ok. This however is very uncommon pattern and your library users might reject it so keep that in mind if you are going to make public library. Other than that I would suggest at least to make that cast method to return a shallow copy because messing with "this" ptr can be dangerous (make sure to try it with const objects and optimized release builds before using this everywhere). An even better (at least safer, in theory) option would be to make "View" or handle struct that wraps an object(pointer) and tracks such transformations. Of course to think of it now there is yet another opportunity - why not to look for something like ECS then? Because you seem to already treat your objects purely as data containers, that way you can safely detach data from logic and reduce the scope of your components to keep them focused on one task. That is up to you of course.
Re: change object class
On Sunday, 17 September 2023 at 15:05:59 UTC, Vitaliy Fadeev wrote: ... Playground: https://run.dlang.io/is/hjcLCk