July 03, 2008
Moritz wrote:
> So now I have a two dimensional array ready for my classes, but sadly, I cant find any information on how classes can be stored in a multidimensional array and how I can use the instances stored there.
> 
> Ive just guessed and typed:
> 
> int add_element(ScreenElement new_element, uint layer)
> {
> 	if(layer <= layer_count)
> 	{
> 		ScreenElement[] single_layer = layer_map[layer];
> 		single_layer ~= new_element;
> 	}
> 	else
> 	{
> 		writefln("cant insert ScreenElement into non existing layer");
> 	}
> 	return 0;
> }
> 
> Sadly, this doesnt work, I get an Error: ArrayBoundsError upon inserting.
> Can anyone tell me how this is done, and maybe even where I can find usful examples for more cmplex uses of arrays in D?
> 
> My biggest problem ATM is the lack of good tutorials or examples, it seems that D is no easy language to get started with, once you want to do more than basics :-(


Does it work if you make this change?

- 	if(layer <= layer_count)
+ 	if(layer < layer_map.length)
July 03, 2008
torhu schrieb:
> Does it work if you make this change?
> 
> -     if(layer <= layer_count)
> +     if(layer < layer_map.length)

Well, my program DOES work, but I doesnt do what I want it to, because Im now unable to insert ScreenElements into the array.

Do I need to initialize the array slots before I assign an object to them? The way I see it, the array has length 0 at start, and I cant put anything in slot 0 or Ill get an array out of bounds error :-(

My problem is I dont know how to store the ScreenElement instances into the array.

I guess my next problem after storing them will be to keep the garbage collector from deleting them after I leave the function where the ScreenElements  are created and stored into the array, or does the array reference protect the ScreenElements from GC?.
July 03, 2008
"Moritz" <mpipahl@gspgmbh.com> wrote in message news:g4jm5u$1p9r$1@digitalmars.com...
> torhu schrieb:
>> Does it work if you make this change?
>>
>> -     if(layer <= layer_count)
>> +     if(layer < layer_map.length)
>
> Well, my program DOES work, but I doesnt do what I want it to, because Im now unable to insert ScreenElements into the array.
>
> Do I need to initialize the array slots before I assign an object to them? The way I see it, the array has length 0 at start, and I cant put anything in slot 0 or Ill get an array out of bounds error :-(

No, it's because you're using a temp variable when you shouldn't be.

ScreenElement[] single_layer = layer_map[layer]; single_layer ~= new_element;

That will get a reference the layer map at index `layer`, but when you concatenate, only the local single_layer will refer to the newer, longer array.  Just do it in place:

layer_map[layer] ~= new_element;

(Also if you don't feel like typing all those long types for variables, it's completely unnecessary.

auto single_layer = layer_map[layer];

Dah.)

> I guess my next problem after storing them will be to keep the garbage collector from deleting them after I leave the function where the ScreenElements  are created and stored into the array, or does the array reference protect the ScreenElements from GC?.

Arrays are on the heap.  As long as something references said array, the GC won't collect objects the array holds.  That's kind of the point.  The GC isn't out to make your life hard; quite the opposite in fact :)

The GC is actually fairly conservative, and if it's not sure whether something is referenced or not (i.e. say you have some random-looking data, like sound data, and the GC says "hm, this looks like a pointer into an object"), it won't collect it.


July 04, 2008
Moritz wrote:
> 
> @Lars Igesund: I considered Tango, but I had some issues with derelict, so I stopped the installation and decided to give phobos a closer look. 
> 

What issues did you have with Derelict? It works with Tango just fine.
July 04, 2008
Nothing all too serious, but I switched to tango and Derelict then didnt compile, becaue in endian.d there is an import:

private import std.intrinsic;

which is phobos, isnt it? So I kept phobos for the moment.

Mike Parker schrieb:
> Moritz wrote:
>>
>> @Lars Igesund: I considered Tango, but I had some issues with derelict, so I stopped the installation and decided to give phobos a closer look.
> 
> What issues did you have with Derelict? It works with Tango just fine.
July 04, 2008
Moritz wrote:

> Nothing all too serious, but I switched to tango and Derelict then didnt compile, becaue in endian.d there is an import:
> 
> private import std.intrinsic;
> 
> which is phobos, isnt it? So I kept phobos for the moment.

the name std.intrinsic is decided by the compiler, and so is used for both Tango and Phobos.

-- 
Lars Ivar Igesund
blog at http://larsivi.net
DSource, #d.tango & #D: larsivi
Dancing the Tango
July 04, 2008
On Fri, 04 Jul 2008 03:22:03 +0400, Jarrett Billingsley <kb3ctd2@yahoo.com> wrote:

> "Moritz" <mpipahl@gspgmbh.com> wrote in message
> news:g4jm5u$1p9r$1@digitalmars.com...
>> torhu schrieb:
>>> Does it work if you make this change?
>>>
>>> -     if(layer <= layer_count)
>>> +     if(layer < layer_map.length)
>>
>> Well, my program DOES work, but I doesnt do what I want it to, because Im
>> now unable to insert ScreenElements into the array.
>>
>> Do I need to initialize the array slots before I assign an object to them?
>> The way I see it, the array has length 0 at start, and I cant put anything
>> in slot 0 or Ill get an array out of bounds error :-(
>
> No, it's because you're using a temp variable when you shouldn't be.
>
> ScreenElement[] single_layer = layer_map[layer];
> single_layer ~= new_element;
>
> That will get a reference the layer map at index `layer`, but when you
> concatenate, only the local single_layer will refer to the newer, longer
> array.  Just do it in place:
>
> layer_map[layer] ~= new_element;
>
> (Also if you don't feel like typing all those long types for variables, it's
> completely unnecessary.
>
> auto single_layer = layer_map[layer];
>
> Dah.)
>
>> I guess my next problem after storing them will be to keep the garbage
>> collector from deleting them after I leave the function where the
>> ScreenElements  are created and stored into the array, or does the array
>> reference protect the ScreenElements from GC?.
>
> Arrays are on the heap.  As long as something references said array, the GC
> won't collect objects the array holds.  That's kind of the point.  The GC
> isn't out to make your life hard; quite the opposite in fact :)
>
> The GC is actually fairly conservative, and if it's not sure whether
> something is referenced or not (i.e. say you have some random-looking data,
> like sound data, and the GC says "hm, this looks like a pointer into an
> object"), it won't collect it.
>
>

Or, better, use:
auto single_layer = layer in layer_map;

to avoid lookup on insertion:
layer_map[layer] ~= new_element; -> single_layer ~= new_element;

right?
July 04, 2008
"Koroskin Denis" wrote
> On Fri, 04 Jul 2008 03:22:03 +0400, Jarrett Billingsley
>> "Moritz" wrote
>>> torhu schrieb:
>>>> Does it work if you make this change?
>>>>
>>>> -     if(layer <= layer_count)
>>>> +     if(layer < layer_map.length)
>>>
>>> Well, my program DOES work, but I doesnt do what I want it to, because
>>> Im
>>> now unable to insert ScreenElements into the array.
>>>
>>> Do I need to initialize the array slots before I assign an object to
>>> them?
>>> The way I see it, the array has length 0 at start, and I cant put
>>> anything
>>> in slot 0 or Ill get an array out of bounds error :-(
>>
>> No, it's because you're using a temp variable when you shouldn't be.
>>
>> ScreenElement[] single_layer = layer_map[layer]; single_layer ~= new_element;
>>
>> That will get a reference the layer map at index `layer`, but when you concatenate, only the local single_layer will refer to the newer, longer array.  Just do it in place:
>>
>> layer_map[layer] ~= new_element;
>>
>> (Also if you don't feel like typing all those long types for variables,
>> it's
>> completely unnecessary.
>>
>> auto single_layer = layer_map[layer];
>>
>> Dah.)
>>
>>> I guess my next problem after storing them will be to keep the garbage collector from deleting them after I leave the function where the ScreenElements  are created and stored into the array, or does the array reference protect the ScreenElements from GC?.
>>
>> Arrays are on the heap.  As long as something references said array, the
>> GC
>> won't collect objects the array holds.  That's kind of the point.  The GC
>> isn't out to make your life hard; quite the opposite in fact :)
>>
>> The GC is actually fairly conservative, and if it's not sure whether
>> something is referenced or not (i.e. say you have some random-looking
>> data,
>> like sound data, and the GC says "hm, this looks like a pointer into an
>> object"), it won't collect it.
>>
>>
>
> Or, better, use:
> auto single_layer = layer in layer_map;
>
> to avoid lookup on insertion:
> layer_map[layer] ~= new_element; -> single_layer ~= new_element;
>
> right?

According to an earlier post, layer_map is a 2D array, not an associative array.  I think 'in' only works on AA's.

What you could do though is:

auto single_layer = &layer_map[layer];

But I'm not sure ~ works on an array pointer, but D does do some magical stuff with operators when dealing with pointers, so it could work :)

-Steve


July 04, 2008
"Moritz" wrote
> So now I have a two dimensional array ready for my classes, but sadly, I cant find any information on how classes can be stored in a multidimensional array and how I can use the instances stored there.
>
> Ive just guessed and typed:
>
> int add_element(ScreenElement new_element, uint layer)
> {
> if(layer <= layer_count)
> {
> ScreenElement[] single_layer = layer_map[layer];
> single_layer ~= new_element;
> }
> else
> {
> writefln("cant insert ScreenElement into non existing layer");
> }
> return 0;
> }
>
> Sadly, this doesnt work, I get an Error: ArrayBoundsError upon inserting. Can anyone tell me how this is done, and maybe even where I can find usful examples for more cmplex uses of arrays in D?
>
> My biggest problem ATM is the lack of good tutorials or examples, it seems that D is no easy language to get started with, once you want to do more than basics :-(

To help you understand, think of it this way:

ScreenElement[][] is really a dynamic array of dynamic arrays.  In otherwords, it means:

(ScreenElement[])[].

So this starts out empty.  In order to initialize it, say to size 5, you should do:

ScreenElement[][] layer_map = new ScreenElement[][5];

Now, the map has 5 empty ScreenElement[] arrays in it.

It's a lot easier to understand if you alias the ScreenElement[] type:

alias ScreenElement[] layer;

layer[] layer_map = new layer[5];

The thing about D that I like is that it is completely consistent in this regard.  There are no 'special' cases, everything is broken down to the same simple case.  Once you understand that, multi-dimensional arrays become really easy.

-Steve


July 04, 2008
On Fri, 04 Jul 2008 17:40:12 +0400, Steven Schveighoffer <schveiguy@yahoo.com> wrote:

> "Koroskin Denis" wrote
>> On Fri, 04 Jul 2008 03:22:03 +0400, Jarrett Billingsley
>>> "Moritz" wrote
>>>> torhu schrieb:
>>>>> Does it work if you make this change?
>>>>>
>>>>> -     if(layer <= layer_count)
>>>>> +     if(layer < layer_map.length)
>>>>
>>>> Well, my program DOES work, but I doesnt do what I want it to, because
>>>> Im
>>>> now unable to insert ScreenElements into the array.
>>>>
>>>> Do I need to initialize the array slots before I assign an object to
>>>> them?
>>>> The way I see it, the array has length 0 at start, and I cant put
>>>> anything
>>>> in slot 0 or Ill get an array out of bounds error :-(
>>>
>>> No, it's because you're using a temp variable when you shouldn't be.
>>>
>>> ScreenElement[] single_layer = layer_map[layer];
>>> single_layer ~= new_element;
>>>
>>> That will get a reference the layer map at index `layer`, but when you
>>> concatenate, only the local single_layer will refer to the newer, longer
>>> array.  Just do it in place:
>>>
>>> layer_map[layer] ~= new_element;
>>>
>>> (Also if you don't feel like typing all those long types for variables,
>>> it's
>>> completely unnecessary.
>>>
>>> auto single_layer = layer_map[layer];
>>>
>>> Dah.)
>>>
>>>> I guess my next problem after storing them will be to keep the garbage
>>>> collector from deleting them after I leave the function where the
>>>> ScreenElements  are created and stored into the array, or does the array
>>>> reference protect the ScreenElements from GC?.
>>>
>>> Arrays are on the heap.  As long as something references said array, the
>>> GC
>>> won't collect objects the array holds.  That's kind of the point.  The GC
>>> isn't out to make your life hard; quite the opposite in fact :)
>>>
>>> The GC is actually fairly conservative, and if it's not sure whether
>>> something is referenced or not (i.e. say you have some random-looking
>>> data,
>>> like sound data, and the GC says "hm, this looks like a pointer into an
>>> object"), it won't collect it.
>>>
>>>
>>
>> Or, better, use:
>> auto single_layer = layer in layer_map;
>>
>> to avoid lookup on insertion:
>> layer_map[layer] ~= new_element; ->
>> right?
>
> According to an earlier post, layer_map is a 2D array, not an associative
> array.  I think 'in' only works on AA's.
>
> What you could do though is:
>
> auto single_layer = &layer_map[layer];
>
> But I'm not sure ~ works on an array pointer, but D does do some magical
> stuff with operators when dealing with pointers, so it could work :)
>
> -Steve
>
>

You are right. It should be
*single_layer ~= new_element;

And yes, `in` doesn't work for dynamic arrays, although it could (for consistency and generality).