change object class

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

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``` ?



dlang custom keyword for struct/class

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

Is it possible to write like this in D?

```d
struct Message
{
   ulong timestamp;
}

Message LongMessage
{
ubyte[255] s;
}
//
// it mean
//
// struct LongMessage
// {
// Message _super;
// alias _super this;
// ubyte[255] s;
// }
//
// or
//
// struct LongMessage
// {
// ulong timestamp;
// ubyte[255] s;
// }
```

Is it possible?



Re: dlang custom keyword for struct/class

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

Is it possible to write like this in D?

```d
struct Message
{
   ulong timestamp;
}

Message LongMessage
{
ubyte[255] s;
}
//
// it mean
//
// struct LongMessage
// {
// Message _super;
// alias _super this;
// ubyte[255] s;
// }
//
// or
//
// struct LongMessage
// {
// ulong timestamp;
// ubyte[255] s;
// }
```

Is it possible?


No, there's no struct inheritance. But you can just write the 
`alias this` version manually.


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




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.



Dinamyc arrays

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

I`ve just started learning d and have a question.
What should I write to set dinamyc rectangular array length in 
both dimentions?

For example, I have declareted an array:
```   int[][] matrix;```
and want set it as n*n matrix.
Thanks




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: Dinamyc arrays

2023-09-17 Thread Salih Dincer via Digitalmars-d-learn

On Sunday, 17 September 2023 at 17:15:34 UTC, Timofey wrote:

I`ve just started learning d and have a question.
What should I write to set dinamyc rectangular array length in 
both dimentions?

For example, I have declareted an array:
```   int[][] matrix;```
and want set it as n*n matrix.
Thanks



There are many ways to do this, but I can quickly show you two:

```d
import std.stdio;
void main()
{
int[][] matrix;
    enum n = 6;

// method 1:
    //matrix = new int[][](n, n); /*

// method 2:
    matrix.length = n;
    foreach(ref e; matrix)
        e.length = n;//*/
    
matrix.writeln;
}
```

SDB@79


Re: Help on array pointers

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

On Friday, 15 September 2023 at 16:55:34 UTC, Vino wrote:

On Friday, 15 September 2023 at 15:27:00 UTC, Vino wrote:

On Friday, 15 September 2023 at 02:25:09 UTC, Joe wrote:

On Thursday, 14 September 2023 at 14:21:09 UTC, Vino wrote:

[...]


A pointer is a type that points to something. It's literally 
that simple. Every piece of data and code exist somewhere in 
memory. Every piece of memory has an address. The address is 
what a pointer contains. Sometimes we want a type that is the 
address itself rather than a value/number.


[...]


Hi Joe,
Thank you very much for the explanation can you please correct 
me if my understanding is incorrect

```
byte[] z; // Creates an array of bytes. That is, the compiler 
will create a pointer to an array of memory and track it's 
length and deal with memory allocation and all that.

```
If we use the above method then :


The compiler takes care of initilizing the array and free the 
memory after the usage.

And this is the recommended method.

```
We can use a pointer as an array also, this is the "old school 
way of creating arrays".

int qlen = 5;
int* q = cast(int*)malloc(int.sizeof*qlen);
``` 
If we use the above method then :
We need to manual initilize the array.
Ensure that the memory is freed after the usage using 
try/final block.


By default the memory allocation for arrays in D is based on 
GC (expect for std.array containers) if we want to 
reduce/avoid GC then we need to use the old school way of 
creating the arrays.


In case of using the old school ways then can you guide me 
what is wrong in my earlier code that I am getting the below 
error and how do I correct the same.


Error
```
Invalid Name passed: /T
double free or corruption (out)
Error: program killed by signal 6
```


Hi All,

 At last was able to resolve the issue, but not sure 
whether this is the reight solution.


Code:
```
import std.stdio: writeln;
import std.exception: enforce;
import std.range: empty;
import std.format: format;

auto ref testNames(in string[] names) {
  enforce(!empty(names), "Names cannot be Empty or Null");

 import core.stdc.stdlib;
 import std.algorithm: any, canFind;

 string[] _names;
 size_t len = 19;
 char[] invalid = (cast(char*)malloc(char.sizeof * 
len))[0..len];

 invalid[0 ..len] = 0; //Array Initlization

 try {
   version(Posix) {
  invalid = 
['\'','\"',':',';','*','&','/','[',']','-','+','$','#','<','>','{','}','(',')'];

  }

  foreach(i; names.dup) {
  auto result = i.any!(a => invalid.canFind(a));
  if(result) { throw new Exception("Invalid Name 
passed: %s".format(i)); }

  else {_names = names.dup; return _names; }
  }
} catch(Exception e) { writeln(e.msg);  }
  finally { invalid = null; free(invalid.ptr); } // 
added invalid = null resolved the issue

 return _names;
}

void main () {
writeln(testNames(["/T"]));
}

From,
Vino



char[] invalid = (cast(char*)malloc(char.sizeof * len))[0..len];

This is not the way to go about it. You are mixing "pointer 
arrays" with "arrays".


You are creating a pointer array then turning that in to an 
array. There is no need to do that. Basically you are copying 
what the compiler already does for you.


When you are using arrays([] language) you don't have to worry 
about anything. Just use them as arrays directly and let the 
compiler deal with memory management. The entire point of 
"managed arrays" is to avoid having to manually deal with memory 
which can cause problems if one is not careful.


Of course you have to make sure your array used used correctly 
but that should be obvious.




char[] invalid = (cast(char*)malloc(char.sizeof * len))[0..len];

is exactly the same as

char[] invalid. EXCEPT that you've forced it to be initialized 
with a length of len and went from D in to C then back to D just 
to create an array. You are making it much more complex than it 
needs to be. There are good tutorials on D arrays that you should 
look over. You will see how easy they are.


You could just do char[] invalid = new char[](len); for the same 
effect but is nicer. New understands char, malloc only 
understands bytes. You should not use malloc in D unless you 
explicitly know you need to use it. Malloc is primitive memory 
management.


When you use D's symantics for arrays it is much easier... which 
is the entire point. You don't even need to free the arrays. D 
knows they are local variable sand will free them when out of 
scope. It will grow them when they need to grow, etc.


invalid = null; free(invalid.ptr);

That does nothing. you set invalid.ptr to null and are freeing 
null so you are not freeing the array.


You don't have to though, the array will be free out of scope(not 
in final though so exceptions could cause memory leak) because it 
is a D array.


Do not 

Re: Dinamyc arrays

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

On Sunday, 17 September 2023 at 17:15:34 UTC, Timofey wrote:

I`ve just started learning d and have a question.
What should I write to set dinamyc rectangular array length in 
both dimentions?

For example, I have declareted an array:

```d
int[][] matrix;
```

and want set it as n*n matrix.
Thanks


You can flatten the mat and use operator overloads. Here's a some 
basic code to get started:


```d
struct SquaredMat(T)
{
size_t dim;
T[] array;

this(usize dim)
{
this.dim = dim;
array.length = dim * dim;
}

auto opIndex(size_t x, size_t y)
{
return array[x * dim + y];
}

auto opIndexAssign(size_t x, size_t y, T value)
{
array[x * dim + y] = value;
return this;
}
}
```

Those kind of type should already exist in 3rd part native D 
libraries, e.g "MIR" has something called "NDSlice" IIRC.


Re: Help on array pointers

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

On Sunday, 17 September 2023 at 18:28:36 UTC, Joe wrote:

On Friday, 15 September 2023 at 16:55:34 UTC, Vino wrote:

[...]



[...]



char[] invalid = (cast(char*)malloc(char.sizeof * len))[0..len];

This is not the way to go about it. You are mixing "pointer 
arrays" with "arrays".


[...]


Thank you very much, I am still newbie for programming and 
currently concentrating on Arrays/Struct/Pointers/Memory 
management.