Re: change object class

2023-09-23 Thread Christian Köstlin via Digitalmars-d-learn

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

2023-09-23 Thread Christian Köstlin via Digitalmars-d-learn

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

2023-09-22 Thread Vitaliy Fadeev via Digitalmars-d-learn
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

2023-09-22 Thread Vitaliy Fadeev via Digitalmars-d-learn

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

2023-09-22 Thread Vitaliy Fadeev via Digitalmars-d-learn
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

2023-09-22 Thread Imperatorn via Digitalmars-d-learn
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

2023-09-22 Thread Christian Köstlin via Digitalmars-d-learn

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

2023-09-22 Thread Vitaliy Fadeev via Digitalmars-d-learn

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

2023-09-22 Thread Imperatorn via Digitalmars-d-learn
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

2023-09-21 Thread Vitaliy Fadeev via Digitalmars-d-learn
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

2023-09-21 Thread Vitaliy Fadeev via Digitalmars-d-learn
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

2023-09-21 Thread Vitaliy Fadeev via Digitalmars-d-learn

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

2023-09-21 Thread Imperatorn via Digitalmars-d-learn
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

2023-09-17 Thread Johan via Digitalmars-d-learn

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

2023-09-17 Thread evilrat via Digitalmars-d-learn
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

2023-09-17 Thread Vitaliy Fadeev via Digitalmars-d-learn
On Sunday, 17 September 2023 at 15:05:59 UTC, Vitaliy Fadeev 
wrote:

...


Playground: https://run.dlang.io/is/hjcLCk