|
2 registered members (3run, AndrewAMD),
667
guests, and 1
spider. |
|
Key:
Admin,
Global Mod,
Mod
|
|
|
PANEL function don't stop...
#380494
08/18/11 10:20
08/18/11 10:20
|
mercuryus
OP
Unregistered
|
mercuryus
OP
Unregistered
|
Hi! I have a problem with lite-c. I create some PANELS and call a function for each (pan_fct). Then I remove the PANELS (and with it stop it's single function). But this don't happen - the functions still run (with an undefined pointer to the PANEL [even without an error]. I'm confused... Use F11 to show the statistics (see-> fnc)
///////////////////////////////
#include <acknex.h>
#include <default.c>
///////////////////////////////
BMAP* bmp_test;
PANEL* my_pan[100];
int i;
// test function
void pan_fct(PANEL* p){
while(p!=NULL){
p.angle+=time_step;
wait(1);
}
error("panel fct stopped!");
}
void main(){
// load level
level_load(NULL);
wait(3);
// create bmap
bmp_test=bmap_createblack(64,64,32);
bmap_fill(bmp_test, vector(200, 200, 200), 100);
// create panels array and call a function with each
for(i=0;i<100;i++){
my_pan[i]=pan_create("bmap=bmp_test;flags=VISIBLE;pos_x=200;pos_y=200;",1);
my_pan[i].pos_x+=i*5;
pan_fct(my_pan[i]);
}
// wait for SPACE-key
while(!key_space)wait(1);
// remove the panels (and stop it's function)
for(i=0;i<100;i++){
ptr_remove(my_pan[i]);
my_pan[i]=NULL;
}
while(1)wait(1);
}
What's wrong here?
|
|
|
Re: PANEL function don't stop...
[Re: ]
#380498
08/18/11 10:57
08/18/11 10:57
|
Joined: Feb 2010
Posts: 320 TANA/Madagascar
3dgs_snake
Senior Member
|
Senior Member
Joined: Feb 2010
Posts: 320
TANA/Madagascar
|
Hi, I think it's because the panel pointer used in the function is still pointing to the last memory area used by the function parameter when calling the function, so it is not NULL (I don't know why but the engine does not generate an error if you access a field of the ptr_remove(d) panel). I think the solution is to put a state in you panel, test the state in the while loop and ptr_remove the panel when leaving the loop. In my example below, I check the panel in the array every time to see if it is still valid.
///////////////////////////////
#include <acknex.h>
#include <default.c>
///////////////////////////////
BMAP* bmp_test;
PANEL* my_pan[100];
int i;
// test function
void pan_fct(int i){
while(my_pan[i] != NULL){
PANEL *p = my_pan[i];
p.angle+=time_step;
wait(1);
}
error("panel fct stopped!");
}
void main(){
// load level
level_load(NULL);
wait(3);
// create bmap
bmp_test=bmap_createblack(64,64,32);
bmap_fill(bmp_test, vector(200, 200, 200), 100);
// create panels array and call a function with each
for(i=0;i<100;i++){
my_pan[i]=pan_create("bmap=bmp_test;flags=VISIBLE;pos_x=200;pos_y=200;",1);
my_pan[i].pos_x+=i*5;
pan_fct(i);
}
// wait for SPACE-key
while(!key_space)wait(1);
// remove the panels (and stop it's function)
for(i=0;i<100;i++){
ptr_remove(my_pan[i]);
my_pan[i]=NULL;
}
while(1)wait(1);
}
This is also another example, using panel skill_x for the while loop test.
///////////////////////////////
#include <acknex.h>
#include <default.c>
///////////////////////////////
BMAP* bmp_test;
PANEL* my_pan[100];
int i;
// test function
void pan_fct(PANEL *p){
while(p->skill_x == 100){
p.angle+=time_step;
wait(1);
}
//error("panel fct stopped!");
ptr_remove(p);
}
void main(){
// load level
level_load(NULL);
wait(3);
// create bmap
bmp_test=bmap_createblack(64,64,32);
bmap_fill(bmp_test, vector(200, 200, 200), 100);
// create panels array and call a function with each
for(i=0;i<100;i++){
my_pan[i]=pan_create("bmap=bmp_test;flags=VISIBLE;pos_x=200;pos_y=200;",1);
my_pan[i].pos_x+=i*5;
my_pan[i].skill_x = 100;
pan_fct(my_pan[i]);
}
// wait for SPACE-key
while(!key_space)wait(1);
// remove the panels (and stop it's function)
for(i=0;i<100;i++){
// Kill panel
my_pan[i].skill_x = 0;
my_pan[i]=NULL;
}
while(1)wait(1);
}
Best regards.
|
|
|
Re: PANEL function don't stop...
[Re: 3dgs_snake]
#380514
08/18/11 14:56
08/18/11 14:56
|
mercuryus
OP
Unregistered
|
mercuryus
OP
Unregistered
|
Thanx but this way the function has to "know" the panel/array. This is not the idea of a function in general.
Have to work like an ENTITY*
Anyone an idea - or is this just an other bug?
|
|
|
Re: PANEL function don't stop...
[Re: ]
#380529
08/18/11 18:07
08/18/11 18:07
|
Joined: Apr 2007
Posts: 3,751 Canada
WretchedSid
Expert
|
Expert
Joined: Apr 2007
Posts: 3,751
Canada
|
Its not a bug, its how pointers and functions work. Your best bet would be a pointer to a pointer, this way you could check if the pointer is equal to NULL and then return from the function.
That it doesn't work like actions for entities is also not very surprising given the fact that they rely on the scheduler which will just not jump back to the function if the my of the function entity got removed. Your panel is not the my entity and thus the scheduler doesn't check this before jumping back into your function.
Shitlord by trade and passion. Graphics programmer at Laminar Research. I write blog posts at feresignum.com
|
|
|
Re: PANEL function don't stop...
[Re: WretchedSid]
#380562
08/19/11 07:59
08/19/11 07:59
|
mercuryus
OP
Unregistered
|
mercuryus
OP
Unregistered
|
Yes - this is the solution. There should be a "safe_remove" macro (ptr_remove) for this but it not exists.
///////////////////////////////
#include <acknex.h>
#include <default.c>
///////////////////////////////
BMAP* bmp_test;
PANEL* my_pan[100];
int i;
// test function
void pan_fct(PANEL* p){
long lvp = ptr_for_handle(handle(p)); // store panels pointer
// while p still exists
while(ptr_for_handle(handle(p))==lvp){
p.angle+=time_step;
wait(1);
}
}
void main(){
// load level
level_load(NULL);
wait(3);
// create bmap
bmp_test=bmap_createblack(64,64,32);
bmap_fill(bmp_test, vector(200, 200, 200), 100);
// create panels array and call a function with each
for(i=0;i<100;i++){
my_pan[i]=pan_create("bmap=bmp_test;flags=VISIBLE;pos_x=200;pos_y=200;",1);
my_pan[i].pos_x+=i*5;
pan_fct(my_pan[i]);
}
// wait for SPACE-key
while(!key_space)wait(1);
// remove the panels (and stop it's function)
for(i=0;i<100;i++){
ptr_remove(my_pan[i]);
&my_pan[i]=0;
}
while(1)wait(1);
}
|
|
|
Re: PANEL function don't stop...
[Re: ]
#380676
08/20/11 12:57
08/20/11 12:57
|
Joined: Apr 2007
Posts: 3,751 Canada
WretchedSid
Expert
|
Expert
Joined: Apr 2007
Posts: 3,751
Canada
|
What should the save_remove() macro do? Tracing through the heap and stack to nullify everything that points to the freed memory block is extremely expensive. It will also lead to false/positive results when the address of the memory block is the same as the value of another variable on a stack or the heap.
Shitlord by trade and passion. Graphics programmer at Laminar Research. I write blog posts at feresignum.com
|
|
|
Re: PANEL function don't stop...
[Re: WretchedSid]
#380695
08/20/11 16:24
08/20/11 16:24
|
mercuryus
OP
Unregistered
|
mercuryus
OP
Unregistered
|
Now you're 20% cooler you can try the next step of evolution: "think positive"
An example: *(lets see.. hmmm... YES: your last post)* Instead of criticizing my fault you then can find a proper solution to post.
Thanx anyhow.
|
|
|
Re: PANEL function don't stop...
[Re: ]
#380703
08/20/11 17:20
08/20/11 17:20
|
Joined: Jul 2008
Posts: 894
TechMuc
User
|
User
Joined: Jul 2008
Posts: 894
|
quoting sid Your best bet would be a pointer to a pointer, this way you could check if the pointer is equal to NULL and then return from the function.
///////////////////////////////
#include <acknex.h>
#include <default.c>
///////////////////////////////
BMAP* bmp_test;
PANEL* my_pan[100];
int i;
// test function
void pan_fct(PANEL** p){
PANEL** p_tmp = p;
// while p still exists
while(*p_tmp != 0){
(*p_tmp)->angle+=time_step;
wait(1);
}
}
void main(){
// load level
level_load(NULL);
wait(3);
// create bmap
bmp_test=bmap_createblack(64,64,32);
bmap_fill(bmp_test, vector(200, 200, 200), 100);
// create panels array and call a function with each
for(i=0;i<100;i++){
my_pan[i]=pan_create("bmap=bmp_test;flags=VISIBLE;pos_x=200;pos_y=200;",1);
my_pan[i].pos_x+=i*5;
pan_fct(&my_pan[i]);
}
// wait for SPACE-key
while(!key_space)wait(1);
// remove the panels (and stop it's function)
for(i=0;i<100;i++){
ptr_remove(my_pan[i]);
my_pan[i]=0;
}
while(1)wait(1);
}
|
|
|
Re: PANEL function don't stop...
[Re: ]
#380719
08/20/11 23:00
08/20/11 23:00
|
Joined: Apr 2007
Posts: 3,751 Canada
WretchedSid
Expert
|
Expert
Joined: Apr 2007
Posts: 3,751
Canada
|
An example: *(lets see.. hmmm... YES: your last post)* Instead of criticizing my fault you then can find a proper solution to post. I was curious what you thought the solution could be instead of criticizing you. The problem is that this trivial task requires a huge overhead due to the languages nature. This is common for all C based languages, not only Lite-C and can't be solved with a simple macro. It requires a massive change in variable handling which would have an extreme performance impact not really worth the few cases where it would be useful (they can be solved differently too). Thats why I was curious how you would solve the problem and I still am. My solution is the following: Learn how to use pointers. Simple, no overhead and proven to work in 10 out of 10 cases.
Shitlord by trade and passion. Graphics programmer at Laminar Research. I write blog posts at feresignum.com
|
|
|
Re: PANEL function don't stop...
[Re: WretchedSid]
#380951
08/23/11 05:36
08/23/11 05:36
|
mercuryus
OP
Unregistered
|
mercuryus
OP
Unregistered
|
So it's a huge task for c/c++ (lite-c) to solve such a simple pointer thing. My associate also told me. Thank god c/c++ is dying.
|
|
|
|