Jump to page: 1 2 3
Thread overview
help. resizing dynamic array of a sound effect class.
Jun 28, 2004
clayasaurus
Jun 28, 2004
Brian
Jun 28, 2004
Regan Heath
Jun 29, 2004
clayasaurus
Jun 29, 2004
clayasaurus
Jun 29, 2004
Regan Heath
Jun 29, 2004
clayasaurus
Jun 29, 2004
Regan Heath
Jun 29, 2004
clayasaurus
Jun 29, 2004
Regan Heath
Jun 29, 2004
Arcane Jill
Jun 29, 2004
pragma
Jun 29, 2004
Bent Rasmussen
Jun 29, 2004
pragma
Jun 29, 2004
Bent Rasmussen
Jun 30, 2004
Regan Heath
Jun 30, 2004
Regan Heath
Jun 29, 2004
Andy Friesen
Jun 29, 2004
clayasaurus
Jun 29, 2004
Ben Hinkle
Jun 29, 2004
clayasaurus
June 28, 2004
hello. i'm trying to make it so in my game engine sound effects are dynamic.

That is, you add a sound effect to the manager, play it, and when it is done playing, you remove it. every frame i run a process called 'process' which checks to see if the sound effects are done playing, and if it does, it deletes them.

i've tried deleting the sound effects using the 'delete soundFX[index];' command, but this gives me a segmentation fault. instead i'm using my own sloppy function 'removeSoundFXInArray(soundFX, num)'. this function seems to work and doesn't cause a crash (well as long as not too many sounds are playing, i think i can fix this though)


here is the supplemental code...

void process()
{
for (int i = 0; i < soundFX.length; i++) // delete the soundFX if they are not
playing
{
if (!soundFX[i].playing()) // if soundFX is not playing
{
//delete soundFX[i]; // theoretically, this should work, it doesn't
soundFX = removeSoundFXInArray(soundFX, i); // this does, but it's slower

printf("soundfx done playing. deleted.\n");
}
}
}


SoundFX[] removeSoundFXInArray(inout SoundFX array[], int remove) {// removes a value in an array and returns the new value SoundFX newarray[];

newarray = array[0 .. (remove)];
newarray ~= array[(remove+1) .. array.length];

delete array[remove]; // so it doesn't hang around in memory

return newarray;
}

anyway, i'd figured i was doing something wrong with the delete operator in 'delete soundFX[i]' which was causing the seg fault. It crashes as soon as it tries to delete it that way. but my other way works for some reason.

i'm not sure what i'd be doing wrong though. i'd appreciate some help. thx :)



June 28, 2004
In article <cbpv4s$2287$1@digitaldaemon.com>, clayasaurus says...
>
>hello. i'm trying to make it so in my game engine sound effects are dynamic.
>
>That is, you add a sound effect to the manager, play it, and when it is done playing, you remove it. every frame i run a process called 'process' which checks to see if the sound effects are done playing, and if it does, it deletes them.
>
>i've tried deleting the sound effects using the 'delete soundFX[index];' command, but this gives me a segmentation fault. instead i'm using my own sloppy function 'removeSoundFXInArray(soundFX, num)'. this function seems to work and doesn't cause a crash (well as long as not too many sounds are playing, i think i can fix this though)
>
>
>here is the supplemental code...
>
>void process()
>{
>for (int i = 0; i < soundFX.length; i++) // delete the soundFX if they are not
>playing
>{
>if (!soundFX[i].playing()) // if soundFX is not playing
>{
>//delete soundFX[i]; // theoretically, this should work, it doesn't
>soundFX = removeSoundFXInArray(soundFX, i); // this does, but it's slower
>
>printf("soundfx done playing. deleted.\n");
>}
>}
>}
>
>
>SoundFX[] removeSoundFXInArray(inout SoundFX array[], int remove) {// removes a value in an array and returns the new value SoundFX newarray[];
>
>newarray = array[0 .. (remove)];
>newarray ~= array[(remove+1) .. array.length];
>
>delete array[remove]; // so it doesn't hang around in memory
>
>return newarray;
>}
>
>anyway, i'd figured i was doing something wrong with the delete operator in 'delete soundFX[i]' which was causing the seg fault. It crashes as soon as it tries to delete it that way. but my other way works for some reason.
>
>i'm not sure what i'd be doing wrong though. i'd appreciate some help. thx :)

Is it crashing at delete or is it crashing the next time around when you call soundfx[i].playing on a null pointer. which is fixed by your remove function.


June 28, 2004
On Mon, 28 Jun 2004 21:04:13 +0000 (UTC), Brian <Brian_member@pathlink.com> wrote:
> In article <cbpv4s$2287$1@digitaldaemon.com>, clayasaurus says...
>>
>> hello. i'm trying to make it so in my game engine sound effects are dynamic.
>>
>> That is, you add a sound effect to the manager, play it, and when it is done
>> playing, you remove it. every frame i run a process called 'process' which
>> checks to see if the sound effects are done playing, and if it does, it deletes
>> them.
>>
>> i've tried deleting the sound effects using the 'delete soundFX[index];'
>> command, but this gives me a segmentation fault. instead i'm using my own sloppy
>> function 'removeSoundFXInArray(soundFX, num)'. this function seems to work and
>> doesn't cause a crash (well as long as not too many sounds are playing, i think
>> i can fix this though)
>>
>>
>> here is the supplemental code...
>>
>> void process()
>> {
>> for (int i = 0; i < soundFX.length; i++) // delete the soundFX if they are not
>> playing
>> {
>> if (!soundFX[i].playing()) // if soundFX is not playing
>> {
>> //delete soundFX[i]; // theoretically, this should work, it doesn't
>> soundFX = removeSoundFXInArray(soundFX, i); // this does, but it's slower
>>
>> printf("soundfx done playing. deleted.\n");
>> }
>> }
>> }
>>
>>
>> SoundFX[] removeSoundFXInArray(inout SoundFX array[], int remove)
>> {// removes a value in an array and returns the new value
>> SoundFX newarray[];
>>
>> newarray = array[0 .. (remove)];
>> newarray ~= array[(remove+1) .. array.length];
>>
>> delete array[remove]; // so it doesn't hang around in memory
>>
>> return newarray;
>> }
>>
>> anyway, i'd figured i was doing something wrong with the delete operator in
>> 'delete soundFX[i]' which was causing the seg fault. It crashes as soon as it
>> tries to delete it that way. but my other way works for some reason.
>>
>> i'm not sure what i'd be doing wrong though. i'd appreciate some help. thx :)
>
> Is it crashing at delete or is it crashing the next time around when you call
> soundfx[i].playing on a null pointer. which is fixed by your remove function.

Good call. I reckon if you modify process so that it checks for null entries in your array it will be fixed. Also, why not simply set entries to null instead of deleting, the GC should collect them (as long as you're setting the last reference to null) right?
eg.

foreach(SoundFX fx; soundFX)
{
	if (fx === null) continue;
	if (!fx.playing()) // if soundFX is not playing
	fx = null; //you can do this instead of delete
}	

However, something I just discovered that is disturbing...

void main() {
	char[] test;
	
	test ~= "0";
	test ~= "1";
	test ~= "2";
	test ~= "3";
	test ~= "4";
	test ~= "5";
	test ~= "6";
	test ~= "7";
	test ~= "8";
	test ~= "9";

	foreach(char c; test)
		printf("(%02x) %c\n",c,c);	
	
	printf("\n");
	delete test[4];
	
	foreach(char c; test)
		printf("(%02x) %c\n",c,c);	
}

D:\D\src\build\temp>dmd arr.d
d:\D\dmd\bin\..\..\dm\bin\link.exe arr,,,user32+kernel32/noi;

D:\D\src\build\temp>arr
(30) 0
(31) 1
(32) 2
(33) 3
(34) 4
(35) 5
(36) 6
(37) 7
(38) 8
(39) 9

(30) 0
(31) 1
(32) 2
(33) 3
(00)
(00)
(00)
(00)
(38) 8
(39) 9

It appears to have deleted 32bits (int?) worth of data from the array?!?

Regan.

-- 
Using M2, Opera's revolutionary e-mail client: http://www.opera.com/m2/
June 29, 2004
In article <cbq14d$253l$1@digitaldaemon.com>, Brian says...
>
>Is it crashing at delete or is it crashing the next time around when you call soundfx[i].playing on a null pointer. which is fixed by your remove function.
>
>

now that i think about it, it doesn't seem to crash right on the delete, since i can still printf after the delete.

i guess it must be crashing next time it tries to access the .playing() function. but i thought if i delete an element in an array, the array will be resized and the element will be gone, so it shouldn't even try to access my playing() function ?


June 29, 2004
clayasaurus wrote:
> anyway, i'd figured i was doing something wrong with the delete operator in
> 'delete soundFX[i]' which was causing the seg fault. It crashes as soon as it
> tries to delete it that way. but my other way works for some reason. 
> 
> i'm not sure what i'd be doing wrong though. i'd appreciate some help. thx :)

It looks to me like delete array[x] does not remove an element from an array, but instead calls the destructor of that element.

It's probably best just to do:

    void deleteSFX(inout SoundFX[] array, uint remove) {
        for (uint i = remove; i < array.length - 1; i++) {
            array[i] = array[i + 1];
        }
        array.length = array.length - 1;
    }

 -- andy
June 29, 2004
In article <opsabrr2wv5a2sq9@digitalmars.com>, Regan Heath says...
>
>Good call. I reckon if you modify process so that it checks for null
>entries in your array it will be fixed. Also, why not simply set entries
>to null instead of deleting, the GC should collect them (as long as you're
>setting the last reference to null) right?
>eg.
>
>foreach(SoundFX fx; soundFX)
>{
>	if (fx === null) continue;
>	if (!fx.playing()) // if soundFX is not playing
>	fx = null; //you can do this instead of delete
>}
>
>However, something I just discovered that is disturbing...
>
>void main() {
>	char[] test;
>
>	test ~= "0";
>	test ~= "1";
>	test ~= "2";
>	test ~= "3";
>	test ~= "4";
>	test ~= "5";
>	test ~= "6";
>	test ~= "7";
>	test ~= "8";
>	test ~= "9";
>
>	foreach(char c; test)
>		printf("(%02x) %c\n",c,c);
>
>	printf("\n");
>	delete test[4];
>
>	foreach(char c; test)
>		printf("(%02x) %c\n",c,c);
>}
>
>D:\D\src\build\temp>dmd arr.d d:\D\dmd\bin\..\..\dm\bin\link.exe arr,,,user32+kernel32/noi;
>
>D:\D\src\build\temp>arr
>(30) 0
>(31) 1
>(32) 2
>(33) 3
>(34) 4
>(35) 5
>(36) 6
>(37) 7
>(38) 8
>(39) 9
>
>(30) 0
>(31) 1
>(32) 2
>(33) 3
>(00)
>(00)
>(00)
>(00)
>(38) 8
>(39) 9
>
>It appears to have deleted 32bits (int?) worth of data from the array?!?
>
>Regan.
>

well i took your suggestion and now my code looks like

foreach(SoundFX fx; soundFX)
{
if (fx is null)	continue;

if (!fx.playing()) // if soundFX is not playing
{
fx = null;
}
}

are you sure it is a good solution to rely on the garbage collector to clean up my array ? well anyway, i did a little stress test on it and i didn't see any major performance decrease or anything like that, and it doesn't crash (unlike my previous codes)

btw. before i tried 'delete fx;' and it crashes then, even when i check to see if the array is null. oh well.



June 29, 2004
The statement
 delete x[key];
removes the element with the given key if x is an associative array. If x is
a dynamic array then
 delete x[i];
will call the destructor of the ith element of x. If you will be inserting
and removing elements from arbitrary positions in the array I'd recommend
going with an associative array since removing elements is faster.

clayasaurus wrote:

> hello. i'm trying to make it so in my game engine sound effects are dynamic.
> 
> That is, you add a sound effect to the manager, play it, and when it is done playing, you remove it. every frame i run a process called 'process' which checks to see if the sound effects are done playing, and if it does, it deletes them.
> 
> i've tried deleting the sound effects using the 'delete soundFX[index];' command, but this gives me a segmentation fault. instead i'm using my own sloppy function 'removeSoundFXInArray(soundFX, num)'. this function seems to work and doesn't cause a crash (well as long as not too many sounds are playing, i think i can fix this though)
> 
> 
> here is the supplemental code...
> 
> void process()
> {
> for (int i = 0; i < soundFX.length; i++) // delete the soundFX if they are
> not playing
> {
> if (!soundFX[i].playing()) // if soundFX is not playing
> {
> //delete soundFX[i]; // theoretically, this should work, it doesn't
> soundFX = removeSoundFXInArray(soundFX, i); // this does, but it's slower
> 
> printf("soundfx done playing. deleted.\n");
> }
> }
> }
> 
> 
> SoundFX[] removeSoundFXInArray(inout SoundFX array[], int remove) {// removes a value in an array and returns the new value SoundFX newarray[];
> 
> newarray = array[0 .. (remove)];
> newarray ~= array[(remove+1) .. array.length];
> 
> delete array[remove]; // so it doesn't hang around in memory
> 
> return newarray;
> }
> 
> anyway, i'd figured i was doing something wrong with the delete operator in 'delete soundFX[i]' which was causing the seg fault. It crashes as soon as it tries to delete it that way. but my other way works for some reason.
> 
> i'm not sure what i'd be doing wrong though. i'd appreciate some help. thx :)

June 29, 2004
In article <cbqjab$2u85$1@digitaldaemon.com>, Andy Friesen says...
>
>
>It's probably best just to do:
>
>     void deleteSFX(inout SoundFX[] array, uint remove) {
>         for (uint i = remove; i < array.length - 1; i++) {
>             array[i] = array[i + 1];
>         }
>         array.length = array.length - 1;
>     }
>
>  -- andy

thanks andy, i think i like your solution because my arrays length doesn't climb to drastic heights. in fact when i do

delete soundFX[i]; deleteSFX(soundFX,i);

not only does it call the constructer, but it resizes the array and doesn't crash! woohoo.


June 29, 2004
In article <cbqjoi$2uu9$1@digitaldaemon.com>, Ben Hinkle says...
>
>The statement
> delete x[key];
>removes the element with the given key if x is an associative array. If x is a dynamic array then
> delete x[i];
>will call the destructor of the ith element of x. If you will be inserting and removing elements from arbitrary positions in the array I'd recommend going with an associative array since removing elements is faster.
>
>

ok. i'll keep that in mind for the future. i've never worked with associative arrays before and i'll probably need to play around with them a bit to figure them out.



June 29, 2004
On Tue, 29 Jun 2004 02:09:03 +0000 (UTC), clayasaurus <clayasaurus_member@pathlink.com> wrote:

> In article <cbq14d$253l$1@digitaldaemon.com>, Brian says...
>>
>> Is it crashing at delete or is it crashing the next time around when you call
>> soundfx[i].playing on a null pointer. which is fixed by your remove function.
>>
>>
>
> now that i think about it, it doesn't seem to crash right on the delete, since i
> can still printf after the delete.
>
> i guess it must be crashing next time it tries to access the .playing()
> function. but i thought if i delete an element in an array, the array will be
> resized and the element will be gone

it does not resize the array. (like your function did)

> , so it shouldn't even try to access my
> playing() function ?

I think I gave some bad advice, do you have?

foreach(SoundFX fx; soundFX)

if so, try

foreach(inout SoundFX fx; soundFX)

here is a test program I wrote, as you can see it works with delete :)

import std.random;
import std.date;

class Foo {
	int tick;
	this(int _tick) {
		tick = _tick;
	}
	bool dec()
	{
		if (tick > 0) tick--;
		return tick == 0;
	}
}

void main() {
	Foo[] p;
	int cnt;
	
	rand_seed(getUTCtime(),0);
	p ~= new Foo(rand()&12);
	p ~= new Foo(rand()&12);
	p ~= new Foo(rand()&12);
	p ~= new Foo(rand()&12);
	p ~= new Foo(rand()&12);
	p ~= new Foo(rand()&12);
	p ~= new Foo(rand()&12);
	p ~= new Foo(rand()&12);
	p ~= new Foo(rand()&12);
	
	while(true) {
		cnt = 0;
		foreach(inout Foo f; p)
		{
			if (f is null) continue;
			cnt++;
			
			if (!f.dec()) continue;
			delete f;
		}
		foreach(Foo f2; p)
		{
			if (f2 is null) printf("%x()\n",f2);
			else printf("%x(%d)\n",f2,f2.tick);
		}
		printf("\n");
		if (cnt == 0) break;
	}
}

Regan

-- 
Using M2, Opera's revolutionary e-mail client: http://www.opera.com/m2/
« First   ‹ Prev
1 2 3