digitalmars.D.learn - data containers
- Moritz (13/13) Jul 02 2008 Hello,
- Koroskin Denis (36/49) Jul 02 2008 I like the way it is done in a PopCap Framework (available for free from...
- Jarrett Billingsley (10/23) Jul 02 2008 Well, hashtables are built into the language, though they are not
- Steven Schveighoffer (6/19) Jul 03 2008 I'm not a game programmer, but I did make a collections project for D th...
- Lars Ivar Igesund (7/18) Jul 03 2008 Maybe a reason to consider Tango?
- Moritz (13/30) Jul 03 2008 Thx for all your replies, but I hoped for a hint on how to implement it,...
- Mike Parker (2/6) Jul 03 2008 What issues did you have with Derelict? It works with Tango just fine.
- Moritz (5/12) Jul 03 2008 Nothing all too serious, but I switched to tango and Derelict then didnt...
- Lars Ivar Igesund (8/14) Jul 04 2008 the name std.intrinsic is decided by the compiler, and so is used for bo...
- Moritz (16/16) Jul 03 2008 Another (more practical) question:
- Koroskin Denis (12/28) Jul 03 2008 Works fine for me:
- Moritz (2/2) Jul 03 2008 Thank you, the error was:
- Moritz (23/23) Jul 03 2008 So now I have a two dimensional array ready for my classes, but sadly, I...
- torhu (4/31) Jul 03 2008 Does it work if you make this change?
- Moritz (12/16) Jul 03 2008 Well, my program DOES work, but I doesnt do what I want it to, because
- Jarrett Billingsley (20/34) Jul 03 2008 No, it's because you're using a temp variable when you shouldn't be.
- Koroskin Denis (7/49) Jul 04 2008 Or, better, use:
- Steven Schveighoffer (8/67) Jul 04 2008 According to an earlier post, layer_map is a 2D array, not an associativ...
- Koroskin Denis (6/79) Jul 04 2008 You are right. It should be
- Moritz (33/50) Jul 04 2008 Im sorry, but I still get an ArrayBoundsError upon doing:
- Steven Schveighoffer (17/40) Jul 04 2008 To help you understand, think of it this way:
Hello, Im currently working on a gui framework for my game, and Im trying to find a versatile way to build my screens. I thought about a generic "Screen" class, which has functions like "add_element()" to insert a sprite or text into a layer on the screen. Rendering is then done from the lowest layer to the highest one. My question is now how I can implement these Layers, since I didnt find LikedLists or Hastables in Phobos. My Idea in C++ would be to have a hashtable int to linked list, which gives me the linked list for a layer upon inserting the layer number, and the linked list then contains my ScreenObjects (a base class for images, text, buttons and so on). What would be the best way to do this in D?
Jul 02 2008
On Thu, 03 Jul 2008 01:04:09 +0400, Moritz <mpipahl gspgmbh.com> wrote:Hello, Im currently working on a gui framework for my game, and Im trying to find a versatile way to build my screens. I thought about a generic "Screen" class, which has functions like "add_element()" to insert a sprite or text into a layer on the screen. Rendering is then done from the lowest layer to the highest one. My question is now how I can implement these Layers, since I didnt find LikedLists or Hastables in Phobos. My Idea in C++ would be to have a hashtable int to linked list, which gives me the linked list for a layer upon inserting the layer number, and the linked list then contains my ScreenObjects (a base class for images, text, buttons and so on). What would be the best way to do this in D?I like the way it is done in a PopCap Framework (available for free from developer.popcap.com; Zuma, Peggle, and all the others PopCap games are made with this framework). Everything is a Widget. Widgets can be built into a hierarchically, one nested in another. Child widgets are stored in a linked list (for easy appending and removal during iteration over collection) in an order they are added. This is the same order they are drawn to screen (topmost widget is at the end and drawn last). There are two main phases: Update and Drawing. During update, all widgets' Update() method is called recursively starting from the root of the hierarchy. The same goes for a Drawing. Every widget defines a void Draw(Graphics g); method. All the drawing is done in this method. For example, you may have one big Screen class and do the rendering in a single method. Or, prefferred, have one lots of small widgets on a board, each of them draws itself only. There may be some ImageWidget (constructed from an image and renders static image), AnimatedWidget (constructed from a frame sequence), etc. Fonts are not widgets, but are drawn as a part of some widget. For example, a button with a caption is a single object. Caption is drawn during a button.draw(g) call. Updates and Drawings are transparent to user. User just defines a new class, overrides its draw method and put newly constructed object to a board. That's it! Changing a widget order on the screen is as simple as moving an object inside a list: class Widget { ... void bringToFront(Widget child) { widgets.erase(child); widgets.pushBack(child); } ... } That's it. Hope this info will help you make your design desicions. P.S. Take a look into ArcLib, too: http://www.dsource.org/projects/arclib
Jul 02 2008
"Moritz" <mpipahl gspgmbh.com> wrote in message news:g4gqge$27fi$1 digitalmars.com...Hello, Im currently working on a gui framework for my game, and Im trying to find a versatile way to build my screens. I thought about a generic "Screen" class, which has functions like "add_element()" to insert a sprite or text into a layer on the screen. Rendering is then done from the lowest layer to the highest one. My question is now how I can implement these Layers, since I didnt find LikedLists or Hastables in Phobos. My Idea in C++ would be to have a hashtable int to linked list, which gives me the linked list for a layer upon inserting the layer number, and the linked list then contains my ScreenObjects (a base class for images, text, buttons and so on). What would be the best way to do this in D?Well, hashtables are built into the language, though they are not necessarily the most performant implementation. List[int] table; Phobos doesn't have any built-in data structures, like hashtables or linked lists. Tango does. How necessary they are, I don't know, I've never actually used them. Most of the stuff I need to get done, I can get done with dynamic arrays and associative arrays. And really, if you can't type up a linked list in about 30 seconds, .. well, good luck to you.
Jul 02 2008
"Moritz" wroteHello, Im currently working on a gui framework for my game, and Im trying to find a versatile way to build my screens. I thought about a generic "Screen" class, which has functions like "add_element()" to insert a sprite or text into a layer on the screen. Rendering is then done from the lowest layer to the highest one. My question is now how I can implement these Layers, since I didnt find LikedLists or Hastables in Phobos. My Idea in C++ would be to have a hashtable int to linked list, which gives me the linked list for a layer upon inserting the layer number, and the linked list then contains my ScreenObjects (a base class for images, text, buttons and so on). What would be the best way to do this in D?I'm not a game programmer, but I did make a collections project for D that should support Phobos: www.dsource.org/projects/dcollections If you use it, let me know how it works for you. -Steve
Jul 03 2008
Moritz wrote:Hello, Im currently working on a gui framework for my game, and Im trying to find a versatile way to build my screens. I thought about a generic "Screen" class, which has functions like "add_element()" to insert a sprite or text into a layer on the screen. Rendering is then done from the lowest layer to the highest one. My question is now how I can implement these Layers, since I didnt find LikedLists or Hastables in Phobos.Maybe a reason to consider Tango? -- Lars Ivar Igesund blog at http://larsivi.net DSource, #d.tango & #D: larsivi Dancing the Tango
Jul 03 2008
Thx for all your replies, but I hoped for a hint on how to implement it, since Im new to D. 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. But I bought the tango book, and will surely try tango out after I got some of my game ported and running in D. Steven: Ill try to use arrays first (for the sake of simplicity and to understand a bit more about D), and Ill try your collection afterwards (supplying the missing data containers in a project is surely a great idea, thank you!) And pls forgive me if Im asking silly questions, but thats what beginners usually do :-) Moritz schrieb:Hello, Im currently working on a gui framework for my game, and Im trying to find a versatile way to build my screens. I thought about a generic "Screen" class, which has functions like "add_element()" to insert a sprite or text into a layer on the screen. Rendering is then done from the lowest layer to the highest one. My question is now how I can implement these Layers, since I didnt find LikedLists or Hastables in Phobos. My Idea in C++ would be to have a hashtable int to linked list, which gives me the linked list for a layer upon inserting the layer number, and the linked list then contains my ScreenObjects (a base class for images, text, buttons and so on). What would be the best way to do this in D?
Jul 03 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.
Jul 03 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.
Jul 03 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
Jul 04 2008
Another (more practical) question: Im trying to use a two dimensional array for my ScreenElements: ScreenElement[][] layer_map; Then, Id like to itereate over all the ScreenElements in this array, but I get syntax errors in the inner foreach-loop, on the single_layer identifier. Errormessage: Syntax error on token "single_layer", ; expected after this token foreach(ScreenElement[] single_layer; layer_map[][]) { foreach(ScreenElement element, single_layer) { element.display(); } } Can anyone tell me how to do this correctly?
Jul 03 2008
On Thu, 03 Jul 2008 21:56:17 +0400, Moritz <mpipahl gspgmbh.com> wrote:Another (more practical) question: Im trying to use a two dimensional array for my ScreenElements: ScreenElement[][] layer_map; Then, Id like to itereate over all the ScreenElements in this array, but I get syntax errors in the inner foreach-loop, on the single_layer identifier. Errormessage: Syntax error on token "single_layer", ; expected after this token foreach(ScreenElement[] single_layer; layer_map[][]) { foreach(ScreenElement element, single_layer) { element.display(); } } Can anyone tell me how to do this correctly?Works fine for me: ScreenElement[][] layer_map; foreach(ScreenElement[] single_layer; layer_map) // you may drop [][] as they are not needed { foreach(ScreenElement element; single_layer) // did you have had a typo here? , -> ; { element.display(); } }
Jul 03 2008
Thank you, the error was: "," instead of ";" in foreach(ScreenElement element; single_layer)
Jul 03 2008
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 :-(
Jul 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)
Jul 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?.
Jul 03 2008
"Moritz" <mpipahl gspgmbh.com> wrote in message news:g4jm5u$1p9r$1 digitalmars.com...torhu schrieb: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.)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 :-(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.
Jul 03 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...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?torhu schrieb: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.)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 :-(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.
Jul 04 2008
"Koroskin Denis" wroteOn Fri, 04 Jul 2008 03:22:03 +0400, Jarrett BillingsleyAccording 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"Moritz" wroteOr, better, use: auto single_layer = layer in layer_map; to avoid lookup on insertion: layer_map[layer] ~= new_element; -> single_layer ~= new_element; right?torhu schrieb: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.)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 :-(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.
Jul 04 2008
On Fri, 04 Jul 2008 17:40:12 +0400, Steven Schveighoffer <schveiguy yahoo.com> wrote:"Koroskin Denis" wroteYou 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).On Fri, 04 Jul 2008 03:22:03 +0400, Jarrett BillingsleyAccording 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"Moritz" wroteOr, better, use: auto single_layer = layer in layer_map; to avoid lookup on insertion: layer_map[layer] ~= new_element; -> right?torhu schrieb: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.)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 :-(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.
Jul 04 2008
Im sorry, but I still get an ArrayBoundsError upon doing: layer_map[layer] ~= new_element; Same goes for: auto single_layer = &layer_map[layer]; *single_layer ~= new_element; And whats the point of doing: ScreenElement[][] layer_map = new ScreenElement[][5]; Do I HAVE to initialise a number of empty arrays before concatenating instances of classes into it or not? I dont see the point in giving some lenght in an dynamic array, for this would make it static, or am I wrong? My whole add_element() function looks like this, just to give you all the info: int add_element(ScreenElement new_element, uint layer) { writefln("layer: %d", layer); writefln("layer_map.length: %d", layer_map.length); if(layer <= layer_map.length) { auto single_layer = &layer_map[layer]; *single_layer ~= new_element; //comented out, enalbed this instead of the upper two lines as an alternative //layer_map[layer] ~= new_element; } else { writefln("cant insert ScreenElement into non existing layer"); } return 0; }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.)
Jul 04 2008
Moritz wrote:And whats the point of doing: ScreenElement[][] layer_map = new ScreenElement[][5]; Do I HAVE to initialise a number of empty arrays before concatenating instances of classes into it or not? I dont see the point in giving some lenght in an dynamic array, for this would make it static, or am I wrong?You need to add the layers before you can add ScreenElements to them. Do you have a fixed number of layers? Then what you suggested will work: ScreenElement[][] layer_map = new ScreenElement[][5]; If you are used to working with pointers, dynamic arrays are just that, except that they store the length of what the pointer points to too. It's only that some operations on them actually allocate memory. "~", "~=", and explicitly setting .length allocates. Indexing does not allocate.My whole add_element() function looks like this, just to give you all the info: int add_element(ScreenElement new_element, uint layer) { writefln("layer: %d", layer); writefln("layer_map.length: %d", layer_map.length); if(layer <= layer_map.length) {Replace "<=" with "<", since layer_map.length always is one past the end of the array.
Jul 04 2008
Thank you torhu, I finally managed to get something into this array! :-) But I still dont understand if and how I can add a new ScreenElement array to the layer map *without* setting its size in advance(because I want to remain as generic as possible). My original idea was to have a create_layer() function, which creates a new layer by adding an empty array to the layer map, so I can keep creating as many layers as I want to. And another question: Can I modify the size of an array after I set it manually?You need to add the layers before you can add ScreenElements to them. Do you have a fixed number of layers? Then what you suggested will work: ScreenElement[][] layer_map = new ScreenElement[][5]; If you are used to working with pointers, dynamic arrays are just that, except that they store the length of what the pointer points to too. It's only that some operations on them actually allocate memory. "~", "~=", and explicitly setting .length allocates. Indexing does not allocate.
Jul 04 2008
Moritz wrote:Thank you torhu, I finally managed to get something into this array! :-) But I still dont understand if and how I can add a new ScreenElement array to the layer map *without* setting its size in advance(because I want to remain as generic as possible).I'm wondering if you're aware what a two-dimensional array really is. When you do this: ScreenElement[][] layer_map = new ScreenElement[][5]; layer_map.length will be 5. But the lengths of the arrays in the second dimension will all be zero. For example, layer_map[0].length and layer_map[3].length will be zero. So you have allocated space for 5 arrays of ScreenElements, but no space for the ScreenElements themselves. Just 5 array references that don't have any space to refer to yet. I hope this makes sense to you.And another question: Can I modify the size of an array after I set it manually?Sure, these two will work anytime: array.length = whatever; // set length to whatever array ~= stuff; // increase length by 1, add 'stuff' at end
Jul 05 2008
Thanks again, torhu. I understand multidimensional arrays (at least I think so :-) ), and that these arrays contain pointers to other arrays. I thought the .length() operation would make the array static in its size, thats why I didnt try this earlier. But after reading what you wrote, I still dont see why I cant go without the length(), by just using ~=, like: ScreenElement[][] layer_map; int add_element(ScreenElement new_element, uint layer) { layer_map[layer] ~= new_element; } You wrote setting the length and using ~= both increase the size of the array, but I get an ArrayBoundsError when using the ~=. And thank you all for your help so far!!!! torhu schrieb:Moritz wrote:Thank you torhu, I finally managed to get something into this array! :-) But I still dont understand if and how I can add a new ScreenElement array to the layer map *without* setting its size in advance(because I want to remain as generic as possible).I'm wondering if you're aware what a two-dimensional array really is. When you do this: ScreenElement[][] layer_map = new ScreenElement[][5]; layer_map.length will be 5. But the lengths of the arrays in the second dimension will all be zero. For example, layer_map[0].length and layer_map[3].length will be zero. So you have allocated space for 5 arrays of ScreenElements, but no space for the ScreenElements themselves. Just 5 array references that don't have any space to refer to yet. I hope this makes sense to you.And another question: Can I modify the size of an array after I set it manually?Sure, these two will work anytime: array.length = whatever; // set length to whatever array ~= stuff; // increase length by 1, add 'stuff' at end
Jul 05 2008
Moritz wrote:Thanks again, torhu. I understand multidimensional arrays (at least I think so :-) ), and that these arrays contain pointers to other arrays. I thought the .length() operation would make the array static in its size, thats why I didnt try this earlier. But after reading what you wrote, I still dont see why I cant go without the length(), by just using ~=, like: ScreenElement[][] layer_map; int add_element(ScreenElement new_element, uint layer) { layer_map[layer] ~= new_element; } You wrote setting the length and using ~= both increase the size of the array, but I get an ArrayBoundsError when using the ~=.That probably means you're not doing quite what you think you're doing. Try adding an assert and see if it gets triggered: int add_element(ScreenElement new_element, uint layer) { assert(layer < layer_map.length, "there's no layer with that number"); layer_map[layer] ~= new_element; }And thank you all for your help so far!!!!My pleasure.
Jul 05 2008
If you want more instant help, you could use IRC, it's #D on freenode. Web-based IRC here: http://embed.mibbit.com/?server=irc.freenode.org&channel=%23D
Jul 05 2008
"Moritz" wroteSo 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
Jul 04 2008