Re: Help with Win32: PostQuitMessage(0) doesn't post WM_QUIT apparently, because the message loop is not exited.

2021-08-13 Thread Mike Parker via Digitalmars-d-learn
On Friday, 13 August 2021 at 21:36:35 UTC, Ruby The Roobster 
wrote:




Thank you very much.  The program runs successfully now.


You've got another potential issue you should be aware of. You've 
name a member of your `Skeleton` as `init`. This may cause issues 
at some point, as every type in D has a default `init` property, 
even structs. You shouldn't use that name in any type you define.


Re: Help with Win32: PostQuitMessage(0) doesn't post WM_QUIT apparently, because the message loop is not exited.

2021-08-13 Thread Mike Parker via Digitalmars-d-learn
On Friday, 13 August 2021 at 21:10:38 UTC, Steven Schveighoffer 
wrote:


Well, subtracting the length doesn't do much, you aren't 
actually accessing the array block, you are just changing the 
reference (which lives in thread-local storage). I kind of feel 
like the whole entity table thing is not correct anyway. Did 
you (Mike) also comment out the `did` call? Because that looks 
more suspicious to me. What it is doing is going through all 
the entities from the removed one on and setting their id to 1 
less. HOWEVER, it's not actually *moving* the entities down in 
the array.


I suspected the `did` function first, but the issue persisted 
when I commented out the call in the destructor. I didn't know 
what to think when I found that commenting out the `.length` 
deprecation eliminated it.





I suspect there is a memory access violation or some other 
issue that's causing it to crash rather than exit normally.


It's not crashing. It's hanging.



Re: Help with Win32: PostQuitMessage(0) doesn't post WM_QUIT apparently, because the message loop is not exited.

2021-08-13 Thread Ruby The Roobster via Digitalmars-d-learn
On Friday, 13 August 2021 at 21:10:38 UTC, Steven Schveighoffer 
wrote:

On 8/13/21 3:59 PM, Mike Parker wrote:
On Friday, 13 August 2021 at 16:18:06 UTC, Ruby The Roobster 
wrote:

...

...

...


Well, subtracting the length doesn't do much, you aren't 
actually accessing the array block, you are just changing the 
reference (which lives in thread-local storage). I kind of feel 
like the whole entity table thing is not correct anyway. Did 
you (Mike) also comment out the `did` call? Because that looks 
more suspicious to me. What it is doing is going through all 
the entities from the removed one on and setting their id to 1 
less. HOWEVER, it's not actually *moving* the entities down in 
the array.


However, you will NEVER have an entity be destroyed, because 
there is always a reference to it in the table! They will only 
get destroyed at the end, via `terminate` where things are 
destroyed deterministically.



-Steve



Okay. I removed the destructors and the 'did' function. Instead 
of those, I created a destruct(Entity op) function that works 
without causing an error.  The entitytable array is for the 
purpose of it being easier to search by id, because the index 
used to access the array is the same as the id. It's also(IMO) 
easier on my end to have every Entity object in a single array.





Re: Help with Win32: PostQuitMessage(0) doesn't post WM_QUIT apparently, because the message loop is not exited.

2021-08-13 Thread Ruby The Roobster via Digitalmars-d-learn

On Friday, 13 August 2021 at 19:59:46 UTC, Mike Parker wrote:
You aren't supposed to be manipulating GC-managed memory via 
class destructors. You can not rely on that memory being valid 
at the time that it's accessed in the destructor---the object 
may already have been destroyed. Nondeterministic destruction 
is the price you pay for letting the GC manager your object 
memory.


Of course, in this case, the problem will only crop up at 
termination since the array is declared at module scope so will 
be live up until the GC shuts down. But still, not something 
you should be doing.

...


Thank you very much.  The program runs successfully now.


Re: Help with Win32: PostQuitMessage(0) doesn't post WM_QUIT apparently, because the message loop is not exited.

2021-08-13 Thread Steven Schveighoffer via Digitalmars-d-learn

On 8/13/21 3:59 PM, Mike Parker wrote:

On Friday, 13 August 2021 at 16:18:06 UTC, Ruby The Roobster wrote:

Context for this: I am creating a module of my  own, and this is a 
class contained in the module.  You will notice that after calling 
this class' constructor anywhere in a Win32 API program, that the 
program doesn't close after the window is closed.


You're hanging in `Runtime.terminate`. That's because of your `Entity` 
destructor, specifically this line:


     entitytable.length -= 1;

Comment it out and the program exits successfully.

You aren't supposed to be manipulating GC-managed memory via class 
destructors. You can not rely on that memory being valid at the time 
that it's accessed in the destructor---the object may already have been 
destroyed. Nondeterministic destruction is the price you pay for letting 
the GC manager your object memory.


Of course, in this case, the problem will only crop up at termination 
since the array is declared at module scope so will be live up until the 
GC shuts down. But still, not something you should be doing.


The runtime will help you by throwing an error if you do anything that 
directly triggers an allocation, like calling `new` or performing an 
array append. But it won't help you with anything else.


Someone more versed than I with the GC innards may be able to answer 
whether an error should be thrown here as well, or if this goes under 
the undefined behavior category.


Well, subtracting the length doesn't do much, you aren't actually 
accessing the array block, you are just changing the reference (which 
lives in thread-local storage). I kind of feel like the whole entity 
table thing is not correct anyway. Did you (Mike) also comment out the 
`did` call? Because that looks more suspicious to me. What it is doing 
is going through all the entities from the removed one on and setting 
their id to 1 less. HOWEVER, it's not actually *moving* the entities 
down in the array.


So for instance, if you have 3 entities `[e(0), e(1), e(2)]` then what 
happens when you remove e(1) is it changes their ids to `[e(0), e(0), 
e(1)]` and then resizes the array to strip off the last one, so you get 
the destroyed entity still in the table, and the one that used to be 
e(2) out of the table (though its id is set to 1 now). The result will 
be `[e(0), e(0)]`, with the second one pointing to an invalid block.


However, you will NEVER have an entity be destroyed, because there is 
always a reference to it in the table! They will only get destroyed at 
the end, via `terminate` where things are destroyed deterministically.


I think you are right that he shouldn't be changing that `entitytable` 
thing in the dtor. I also think, the memory management being used there 
is super-sketchy. Without knowing why you need to keep the table around 
in the first place, I'm unsure how it should be fixed.


I suspect there is a memory access violation or some other issue that's 
causing it to crash rather than exit normally.


-Steve


Re: Help with Win32: PostQuitMessage(0) doesn't post WM_QUIT apparently, because the message loop is not exited.

2021-08-13 Thread Mike Parker via Digitalmars-d-learn
On Friday, 13 August 2021 at 16:18:06 UTC, Ruby The Roobster 
wrote:


Context for this: I am creating a module of my  own, and this 
is a class contained in the module.  You will notice that after 
calling this class' constructor anywhere in a Win32 API 
program, that the program doesn't close after the window is 
closed.


You're hanging in `Runtime.terminate`. That's because of your 
`Entity` destructor, specifically this line:


entitytable.length -= 1;

Comment it out and the program exits successfully.

You aren't supposed to be manipulating GC-managed memory via 
class destructors. You can not rely on that memory being valid at 
the time that it's accessed in the destructor---the object may 
already have been destroyed. Nondeterministic destruction is the 
price you pay for letting the GC manager your object memory.


Of course, in this case, the problem will only crop up at 
termination since the array is declared at module scope so will 
be live up until the GC shuts down. But still, not something you 
should be doing.


The runtime will help you by throwing an error if you do anything 
that directly triggers an allocation, like calling `new` or 
performing an array append. But it won't help you with anything 
else.


Someone more versed than I with the GC innards may be able to 
answer whether an error should be thrown here as well, or if this 
goes under the undefined behavior category.


Re: Help with Win32: PostQuitMessage(0) doesn't post WM_QUIT apparently, because the message loop is not exited.

2021-08-13 Thread Ruby The Roobster via Digitalmars-d-learn

On Friday, 13 August 2021 at 03:05:22 UTC, Mike Parker wrote:
On Friday, 13 August 2021 at 00:30:59 UTC, Ruby The Roobster 
wrote:




When I run the program and close the window, the program still 
runs in background mode.  I don't know why this happens nor 
how to fix it.  Does anybody know what's going on?


frame beat me to it, but it may well be that you're getting -1. 
[The documentation][1] says that a window that has already been 
destroyed will result in the `hWnd` parameter being invalid, 
which will cause the function to return -1.



[1]: 
https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getmessage#return-value


After rewriting the program, I figured out that the bug was still 
there. Here is the function that causes it:

```d
public class Entity {
package:
ulong id;
wchar[] name;
static ulong nextid;
Point centre;
Skeleton skeleton;
public:
		this(ulong id, inout(wchar)[] name,Point centre, Skeleton 
skeleton)	{
			assert(init == true, "Error: dutils.entity has not been 
initialized yet. Call dutils.entity.initialize() to initialize 
the library.");

this.id = id;
this.name.length = name.length;
for(uint i = 0; i < name.length; i++){
this.name[i] = name[i];
}
this.nextid = this.id + 1;
this.centre = centre;
if(!skeleton.init)  {
this.skeleton = skeleton;
}
entitytable.length +=1;
entitytable[cast(uint)id] = this;
}

~this() {
entitytable.length -= 1;
this.nextid -=1;
did(cast(uint)this.id);
}

debug immutable(char)[] f() @property   {
import std.format : format;
			return format("ID: %s, Name: %s, NextID: %s, Centre: %s, 
Skeleton: %s", this.id, this.name, this.nextid, this.centre, 
this.skeleton);

}

ulong Id() @property{
return id;
}
}
```

Context for this: I am creating a module of my  own, and this is 
a class contained in the module.  You will notice that after 
calling this class' constructor anywhere in a Win32 API program, 
that the program doesn't close after the window is closed.


Here are the files:

entity.d:
```d
module dutils.entity;

debug { package import core.sys.windows.winuser; } //For 
MessageBoxA in debug messages...


public struct Skeleton  {
public Face[] faces;
package bool init = false;
public this(Face[] faces)   {
this.faces.length = faces.length;
for(uint i = 0; i < faces.length; i++)   {
this.faces[i] = faces[i];
}
}
package this(bool init) {
this.init = init;
}
public void opAssign(Skeleton rhs)  {
this.faces.length = rhs.faces.length;
for(uint i; i < rhs.faces.length; i++)   {
this.faces[i] = rhs.faces[i];
}
this.init = rhs.init;
}
}

public struct Face  {
Point[] points;
Point centre;
void opAssign(Face rhs) {
this.points.length = rhs.points.length;
for(uint i = 0; i < rhs.points.length; i++)  {
this.points[i] = rhs.points[i];
}
this.centre = rhs.centre;
}
}

public struct Point {
real x;
real y;
real z;
void opAssign(Point rhs){
this.x = rhs.x;
this.y = rhs.y;
this.z = rhs.z;
}
}

public class Entity {
package:
ulong id;
wchar[] name;
static ulong nextid;
Point centre;
Skeleton skeleton;
public:
		this(ulong id, inout(wchar)[] name,Point centre, Skeleton 
skeleton)	{
			assert(init == true, "Error: dutils.entity has not been 
initialized yet. Call dutils.entity.initialize() to initialize 
the library.");

this.id = id;
this.name.length = name.length;
for(uint i = 0; i < name.length; i++){
this.name[i] = name[i];
}
this.nextid = this.id + 1;
this.centre = centre;
if(!skeleton.init) 

Re: Help with Win32: PostQuitMessage(0) doesn't post WM_QUIT apparently, because the message loop is not exited.

2021-08-13 Thread Ruby The Roobster via Digitalmars-d-learn

On Friday, 13 August 2021 at 03:05:22 UTC, Mike Parker wrote:
On Friday, 13 August 2021 at 00:30:59 UTC, Ruby The Roobster 
wrote:




When I run the program and close the window, the program still 
runs in background mode.  I don't know why this happens nor 
how to fix it.  Does anybody know what's going on?


frame beat me to it, but it may well be that you're getting -1. 
[The documentation][1] says that a window that has already been 
destroyed will result in the `hWnd` parameter being invalid, 
which will cause the function to return -1.



[1]: 
https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getmessage#return-value


Nevermind. I am just redoing the LRESULT function. Seems to work 
now.


Re: Help with Win32: PostQuitMessage(0) doesn't post WM_QUIT apparently, because the message loop is not exited.

2021-08-13 Thread Ruby The Roobster via Digitalmars-d-learn

On Friday, 13 August 2021 at 03:05:22 UTC, Mike Parker wrote:
On Friday, 13 August 2021 at 00:30:59 UTC, Ruby The Roobster 
wrote:




When I run the program and close the window, the program still 
runs in background mode.  I don't know why this happens nor 
how to fix it.  Does anybody know what's going on?


frame beat me to it, but it may well be that you're getting -1. 
[The documentation][1] says that a window that has already been 
destroyed will result in the `hWnd` parameter being invalid, 
which will cause the function to return -1.



[1]: 
https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getmessage#return-value


So I edited the message loop:
```d
while((b = GetMessage(,hwnd,0,0)) != 0) {
if(exit || b == -1) {
return msg.wParam;
}
TranslateMessage();
DispatchMessage();
}
```
And some of the WndProc:
```d
extern(Windows)
LRESULT WndProc(HWND hwnd, UINT msg, WPARAM wparam, 
LPARAM lparam) nothrow	{

switch(msg) {
case WM_CREATE:
//...
return 0;
break;
case WM_CLOSE:
DestroyWindow(hwnd);
try {
entity.terminate();
exit = true;
}
catch(Throwable e){
}
break;
case WM_DESTROY:
try {
entity.terminate();
exit = true;
}
catch(Throwable e)  {
PostQuitMessage(1);
}
PostQuitMessage(0);
break;
default:
return DefWindowProc(hwnd,msg,wparam,lparam);
}
return 0;
}
```

It still produces the same result(the program never exits), so it 
doesn't look like GetMessage() is returning -1...


Re: Help with Win32: PostQuitMessage(0) doesn't post WM_QUIT apparently, because the message loop is not exited.

2021-08-12 Thread Mike Parker via Digitalmars-d-learn
On Friday, 13 August 2021 at 00:30:59 UTC, Ruby The Roobster 
wrote:




When I run the program and close the window, the program still 
runs in background mode.  I don't know why this happens nor how 
to fix it.  Does anybody know what's going on?


frame beat me to it, but it may well be that you're getting -1. 
[The documentation][1] says that a window that has already been 
destroyed will result in the `hWnd` parameter being invalid, 
which will cause the function to return -1.



[1]: 
https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getmessage#return-value


Re: Help with Win32: PostQuitMessage(0) doesn't post WM_QUIT apparently, because the message loop is not exited.

2021-08-12 Thread frame via Digitalmars-d-learn
On Friday, 13 August 2021 at 00:30:59 UTC, Ruby The Roobster 
wrote:


When I run the program and close the window, the program still 
runs in background mode.  I don't know why this happens nor how 
to fix it.  Does anybody know what's going on?


AFAIK GetMessage() may return -1 if some error happend, so your 
loop won't exit.