Re: linked list
Thanks for the long winded reply Jonathan. I don't know how to avoid using my own linked list, I have next/prev in each class (Ball, Lazer and Mine ) in the list. Thanks bearophile, I had a bit of a look at that site. My game is simple so just maybe the easiest way is the way to go, though if I use the most tightest way and so my game would be an prototype for bigger games to reference.
Re: linked list
On Mon, 27 Sep 2010 10:27:36 +0400, Joel Christensen joel...@gmail.com wrote: Thanks for the long winded reply Jonathan. I don't know how to avoid using my own linked list, I have next/prev in each class (Ball, Lazer and Mine ) in the list. That's called intrusive linked list, and I find using it quite viable: zero-allocation O(1) add/removal is a very strong characteristics. They are very useful especially for lock-free algorithms.
Re: Segmentation fault on closing file in destructor
On Sun, 26 Sep 2010 20:55:33 +0200, Tom Kazimiers wrote: If I would use std.stdio.File, what would be different? Well, for one thing you won't have to write your code all over again when std.stream is deprecated, which will happen soon. std.stdio.File is really what you should use for file I/O in new code. That said, there's a chance it does exactly what you want. You don't have to open a file on construction, there's an open() function which opens a file and assigns it to the File handle. Nor do you have to worry about closing the file in the destructor, as it is automatically closed the moment the last reference to it goes out of scope. Here are a few examples of how to use it: File file;// File's a struct, so no need to use 'new' // Read a text file line by line file.open(foo.txt); foreach (line; file.byLine()) writeln(line); // Read a binary file in 4MB chunks file.open(foo.dat); foreach (ubyte[] chunk; file.byChunk(4*1024)) doStuffWith(chunk); // Read up to 100 ints from a file file.open(myInts); auto buffer = new int[100]; auto data = file.rawRead(buffer); -Lars
Re: linked list, ranges
On Sun, 26 Sep 2010 04:38:36 -0400, Joel Christensen joel...@gmail.com wrote: Thanks again for the reply Jonathan. I'm using doublely linked list I made for a game where ships and there lazer bolts are in the same list. Without linked list I couldn't do things like create a lazer bolt or remove one while trans-versing the linked list. I had to use my own linked list, having a next and prev node in each object that goes in the list. Not sure if dcollections could be of use: http://www.dsource.org/projects/dcollections And the linked list class: http://www.dsource.org/projects/dcollections/browser/branches/d2/dcollections/LinkList.d One thing my lib supports is removal while traversing via foreach. See the purge function. Sorry about lack of online docs, I need to figure out how to automatically generate them (the D1 docs are auto-generated, but I haven't put in any time to figure out how to generate the D2 version). -Steve
Re: Segmentation fault on closing file in destructor
On Sun, 26 Sep 2010 20:20:18 -0400, Michel Fortin michel.for...@michelf.com wrote: On 2010-09-26 10:06:33 -0400, Simen kjaeraas simen.kja...@gmail.com said: Tom Kazimiers 2voo...@gmx.de wrote: Hi, a file reading class of mine can be constructed with a filename as parameter. It instantiates a new std.stream.File (without the passed file name and closes it when opened within the destructor. The last part is where things are getting unclear for me. On the file.isOpen() call in the destructor a segmentation fault occurs. What is the problem with that? Likely, it is this[1]: [T]he order in which the garbage collector calls destructors for unreference objects is not specified. This means that when the garbage collector calls a destructor for an object of a class that has members that are references to garbage collected objects, those references may no longer be valid. This means that destructors cannot reference sub objects. [1]: http://digitalmars.com/d/2.0/class.html#destructors That's it indeed, but I'll add that it's the File struct that is at fault. See this bug: http://d.puremagic.com/issues/show_bug.cgi?id=4624 He's using std.stream.File, not std.stdio.File. In fact, it's generally a good idea to not wait for the GC to collect your objects before closing files, because waiting for the GC could take an indeterminate amount of time and leave files open for a long time (the GC only runs when needed). Yes, this is true no matter what File construct you use. -Steve
Re: Segmentation fault on closing file in destructor
On Sun, 26 Sep 2010 11:17:07 -0400, Tom Kazimiers 2voo...@gmx.de wrote: Hi Simen, On 09/26/2010 04:06 PM, Simen kjaeraas wrote: Likely, it is this[1]: [T]he order in which the garbage collector calls destructors for unreference objects is not specified. This means that when the garbage collector calls a destructor for an object of a class that has members that are references to garbage collected objects, those references may no longer be valid. This means that destructors cannot reference sub objects. [1]: http://digitalmars.com/d/2.0/class.html#destructors thanks for your reply. I did not know that the garbage collector works that way. Is the reason for that flexibility for the GC? What if I want to handle some destruction parts to sub-objects or if I want conditions while destruction, based on sub-objects? Then do not use a destructor. There is no way currently for the destructor to know whether it's being called from the GC or not, so it is only safe to destroy resources *not* allocated by the GC. In fact, the only reason destructors are supported in classes is to destroy non-GC resources. Or maybe I should generally avoid situations like that. Do you have any suggestion how I should make sure that the file gets closed on destruction? You don't have to worry about it -- let the GC do its job. If you think about it, your class instance may have the only reference to the File object. Since your class is being destroyed by the GC, it makes sense that the File object has no references to it, so it too is being destroyed by the GC. If you want sooner destruction, you should manually close it earlier via another function call (like close() or detach()). However, I will mention something that others missed, unlike in C++, the default protection in a class is public, so your public: attribute doesn't do much, and your file member is publicly accessible. -Steve
dcollection docs
On 27.09.2010 14:01, Steven Schveighoffer wrote: Sorry about lack of online docs, I need to figure out how to automatically generate them (the D1 docs are auto-generated, but I haven't put in any time to figure out how to generate the D2 version). -Steve Yao has a nice ddoc template for D2. See for example http://d.yao.com.mx/datetime/core.html The ddoc file is available here: https://bitbucket.org/gomez/yao-library/src/da11956a6a6e/docs/ but I don't know about the license for that file, you might have to ask him about that. This doesn't generate an index though, if you meant that. -- Johannes Pfau
Re: dcollection docs
On Mon, 27 Sep 2010 08:34:57 -0400, Johannes Pfau s...@example.com wrote: On 27.09.2010 14:01, Steven Schveighoffer wrote: Sorry about lack of online docs, I need to figure out how to automatically generate them (the D1 docs are auto-generated, but I haven't put in any time to figure out how to generate the D2 version). -Steve Yao has a nice ddoc template for D2. See for example http://d.yao.com.mx/datetime/core.html The ddoc file is available here: https://bitbucket.org/gomez/yao-library/src/da11956a6a6e/docs/ but I don't know about the license for that file, you might have to ask him about that. This doesn't generate an index though, if you meant that. Thanks, Yao's seems similar to Phobos, which I'm not a big fan of. Particularly the munged-together list of constructs/functions at the top. I used Tango's (old) doc generation templates to generate the D1 docs, and Brad of dsource set up my project to rebuild the D1 docs on every checkin. However, I don't think he's set up a D2 compiler, and even if he did, it's changing so frequently that he'd have to update it too often. I dumped the Tango doc templates for the D2 version, and I want to rewrite them, but I just haven't had the time. In particular, I want a categorical index at the top or on the side (i.e. functions, members, etc.) Having everything munged together is super-confusing. I really like the dil-generated docs that Tango uses, but I'm pretty sure dil isn't D2... -Steve
Dispatching from receive to a function
I've been looking for a way to hook up messages to a thread with a handler function. As far as I can tell receive pattern matching only allows the pattern to be distinguished by the parameter signature which does not help when all the handlers only have a few different signatures. I like the pattern matching concept as I have worked with Erlang which will pattern match to a term (basically an arbitrary structure). Erlang defines an Atom type which is really a global constant that can be used as a message type in the match. Does anyone know of a way to simulate this? Failing that I think a dispatcher structure using an associative array would be my next choice. However I'm getting stuck on how to define and use an array which maps a string key to a delegate. Can someone help me out there please. I will then effectively have my 'Atom' as a string in the message and dispatch on that. I don't want to hard code in a switch statement. Any other suggestions are very welcome. Thanks Bob
Re: Dispatching from receive to a function
On 27.09.2010 15:07, Bob Cowdery wrote: Failing that I think a dispatcher structure using an associative array would be my next choice. However I'm getting stuck on how to define and use an array which maps a string key to a delegate. Can someone help me out there please. I will then effectively have my 'Atom' as a string in the message and dispatch on that. Not sure about the other questions, but here's an example for a string/delegate associative array: --- import std.stdio; alias bool delegate(int, char) TestDelegate; TestDelegate[string] dict; class C { bool test(int i, char c) {return true;} } void main() { C c = new C(); dict[test] = c.test; writeln(dict[test](0, 'c')); } --- -- Johannes Pfau
Re: Dispatching from receive to a function
Thanks. Do you know if the signature is a mandatory part. If I left the signature out would it then only work with a delegate with no parameters? If so I think I'm in the same state as my delegates will not all have the same signature. Bob On 27/09/2010 14:21, Johannes Pfau wrote: On 27.09.2010 15:07, Bob Cowdery wrote: Failing that I think a dispatcher structure using an associative array would be my next choice. However I'm getting stuck on how to define and use an array which maps a string key to a delegate. Can someone help me out there please. I will then effectively have my 'Atom' as a string in the message and dispatch on that. Not sure about the other questions, but here's an example for a string/delegate associative array: --- import std.stdio; alias bool delegate(int, char) TestDelegate; TestDelegate[string] dict; class C { bool test(int i, char c) {return true;} } void main() { C c = new C(); dict[test] = c.test; writeln(dict[test](0, 'c')); } ---
Re: Dispatching from receive to a function
On 27.09.2010 15:36, Bob Cowdery wrote: Thanks. Do you know if the signature is a mandatory part. If I left the signature out would it then only work with a delegate with no parameters? If so I think I'm in the same state as my delegates will not all have the same signature. Yep, the signature is mandatory. There is another, ugly, unsafe (it's safe, but you really have to be careful and write correct code) way: Basically you cast away the delegates type information. You then store the delegate in an array. Later, you have to cast the delegate back to it's original type. The problem here is, that D doesn't provide enough runtime type information to know which type the delegate originally had, so _we_ have to store some type info _manually_. This can for example be done by storing both the delegate and our type info in a struct. Here's an example how to do exactly that. !!!Note: It's very important to always cast the delegate back to the _correct_ type before calling it, everything else leads to undefined behavior!!! So just setting CDelegate.Type to a wrong type can cause a disaster! (Sorry about the bad variable names in the example. For better encapsulation most of the casts could be moved into the CDelegate struct by adding functions and constructors) --- import std.stdio; enum DelegateType { A, B, C, D } struct CDelegate { void delegate() del; //Exact type doesn't matter, all delegates have the same size DelegateType Type; } CDelegate[string] dict; class C { bool test(int i, char c) {return true;} } class D { int test(string s) {return 99;} } void main() { C c = new C(); D d = new D(); CDelegate custom; custom.del = cast(void delegate())c.test; custom.Type = DelegateType.C; dict[c] = custom; custom.del = cast(void delegate())d.test; custom.Type = DelegateType.D; dict[d] = custom; foreach(cdeleg; dict) { switch(cdeleg.Type) { case DelegateType.C: bool delegate(int i, char c) realdel = cast (bool delegate(int i, char c)) cdeleg.del; writeln(realdel(0, 'c')); break; case DelegateType.D: int delegate(string) realdel = cast (int delegate(string)) cdeleg.del; writeln(realdel(test)); break; } } } --- -- Johannes Pfau
Re: Dispatching from receive to a function
I'm new to the language so I don't know if this is horribly wrong on some levels, but it works: - import std.variant; import std.stdio; class C { bool test(int i, char c) { writeln(Hello from test1); return true; } void test2(string v) { writeln(Hello from test2, , v); } } void main() { auto c = new C; Variant[string] holder = [test: Variant(c.test), test2: Variant (c.test2)]; receiver(holder); } void receiver(Variant[string] message) { // If you get the Variant template instantiation delegate // signature wrong, it will // be detected at compile time! auto t = message[test].get!(bool delegate(int, char)); auto t2 = message[test2].get!(void delegate(string)); t(1, 'c'); t2(foo); } -- Curiously if you create holder like this, it will give an arrayoutofbound error at runtime, I don't know if that is a bug: void main() { auto c = new C; Variant[string] holder; holder[test] = Variant(c.test); holder[test2] = Variant(c.test2); } On Mon, 27 Sep 2010 18:03:32 +0200, Johannes Pfau wrote: On 27.09.2010 15:36, Bob Cowdery wrote: Thanks. Do you know if the signature is a mandatory part. If I left the signature out would it then only work with a delegate with no parameters? If so I think I'm in the same state as my delegates will not all have the same signature. Yep, the signature is mandatory. There is another, ugly, unsafe (it's safe, but you really have to be careful and write correct code) way: Basically you cast away the delegates type information. You then store the delegate in an array. Later, you have to cast the delegate back to it's original type. The problem here is, that D doesn't provide enough runtime type information to know which type the delegate originally had, so _we_ have to store some type info _manually_. This can for example be done by storing both the delegate and our type info in a struct. Here's an example how to do exactly that. !!!Note: It's very important to always cast the delegate back to the _correct_ type before calling it, everything else leads to undefined behavior!!! So just setting CDelegate.Type to a wrong type can cause a disaster! (Sorry about the bad variable names in the example. For better encapsulation most of the casts could be moved into the CDelegate struct by adding functions and constructors) --- import std.stdio; enum DelegateType { A, B, C, D } struct CDelegate { void delegate() del; //Exact type doesn't matter, all delegates have the same size DelegateType Type; } CDelegate[string] dict; class C { bool test(int i, char c) {return true;} } class D { int test(string s) {return 99;} } void main() { C c = new C(); D d = new D(); CDelegate custom; custom.del = cast(void delegate())c.test; custom.Type = DelegateType.C; dict[c] = custom; custom.del = cast(void delegate())d.test; custom.Type = DelegateType.D; dict[d] = custom; foreach(cdeleg; dict) { switch(cdeleg.Type) { case DelegateType.C: bool delegate(int i, char c) realdel = cast (bool delegate(int i, char c)) cdeleg.del; writeln(realdel(0, 'c')); break; case DelegateType.D: int delegate(string) realdel = cast (int delegate(string)) cdeleg.del; writeln(realdel(test)); break; } } } ---
Re: Dispatching from receive to a function
On 27.09.2010 20:46, Juanjo Alvarez wrote: I'm new to the language so I don't know if this is horribly wrong on some levels, but it works: - import std.variant; import std.stdio; class C { bool test(int i, char c) { writeln(Hello from test1); return true; } void test2(string v) { writeln(Hello from test2, , v); } } void main() { auto c = new C; Variant[string] holder = [test: Variant(c.test), test2: Variant (c.test2)]; receiver(holder); } void receiver(Variant[string] message) { // If you get the Variant template instantiation delegate // signature wrong, it will // be detected at compile time! auto t = message[test].get!(bool delegate(int, char)); auto t2 = message[test2].get!(void delegate(string)); t(1, 'c'); t2(foo); } -- Curiously if you create holder like this, it will give an arrayoutofbound error at runtime, I don't know if that is a bug: void main() { auto c = new C; Variant[string] holder; holder[test] = Variant(c.test); holder[test2] = Variant(c.test2); } I totally forgot about Variant! As far as I know that's exactly what variant is for and it's way better than my proposed hack. The example you posted is perfectly fine as well. I'm not sure what causes the arrayoutofbound error, the second example is correct as well. -- Johannes Pfau
Re: Dispatching from receive to a function
On Mon, 27 Sep 2010 21:00:48 +0200, Johannes Pfau wrote: On 27.09.2010 20:46, Juanjo Alvarez wrote: I'm new to the language so I don't know if this is horribly wrong on some levels, but it works: - import std.variant; import std.stdio; class C { bool test(int i, char c) { writeln(Hello from test1); return true; } void test2(string v) { writeln(Hello from test2, , v); } } void main() { auto c = new C; Variant[string] holder = [test: Variant(c.test), test2: Variant (c.test2)]; receiver(holder); } void receiver(Variant[string] message) { // If you get the Variant template instantiation delegate // signature wrong, it will // be detected at compile time! auto t = message[test].get!(bool delegate(int, char)); auto t2 = message[test2].get!(void delegate(string)); t(1, 'c'); t2(foo); } -- Curiously if you create holder like this, it will give an arrayoutofbound error at runtime, I don't know if that is a bug: void main() { auto c = new C; Variant[string] holder; holder[test] = Variant(c.test); holder[test2] = Variant(c.test2); } I totally forgot about Variant! As far as I know that's exactly what variant is for and it's way better than my proposed hack. The example you posted is perfectly fine as well. I'm not sure what causes the arrayoutofbound error, the second example is correct as well. Yep, variants are cool. You could even use an struct as value type of the associative array and store the variant in one member and the signature of the delegate, as string, in another member. The you could use a mixin in the receiver to extract the delegate without knowing the original signature. All this is wonderfully disturbing to me :)
Re: dcollection docs
On Mon, 27 Sep 2010 07:34:57 -0500, Johannes Pfau s...@example.com wrote: Yao has a nice ddoc template for D2. See for example http://d.yao.com.mx/datetime/core.html The ddoc file is available here: https://bitbucket.org/gomez/yao-library/src/da11956a6a6e/docs/ but I don't know about the license for that file, you might have to ask him about that. This doesn't generate an index though, if you meant that. That ddoc file is in, let's say, experimental stage, and I had to make some hacks to make the generated docs pass the HTML4 validator (see for example the UL or the D_CODE macros). They don't have licence because I didn't find an equivalent to the Boost Licence but for documentation, but they can be used freely for whatever need you have. I still have to make some improvements, for example create a tree of symbols, like the one in Kandil or CandyDoc. -- Yao G.
Re: dcollection docs
On Mon, 27 Sep 2010 07:46:49 -0500, Steven Schveighoffer schvei...@yahoo.com wrote: Thanks, Yao's seems similar to Phobos, which I'm not a big fan of. Particularly the munged-together list of constructs/functions at the top. To be honest, I don't like it either :) I plan to improve it, and by improve it I mean to remove that cloud-like unordered list of symbols, and use a tree or something similar. CandyDoc sometimes hangs Opera, so I wanted to make a quick replacement, that also worked well without JavaScript. Maybe I'll switch to Kandil or just use the doc generator of Dil. -- Yao G.
Re: Dispatching from receive to a function
Thanks for the suggestions. I'm still hankering after an elegant solution to the receive rather than try to patch it up after the event. The best I can come up with is pretty ugly (odd) at the front but looks better at the back-end. Maybe someone can refine it a bit. struct RATE{}; struct SRC_1{}; struct SRC_2{}; class OutputFrame{ void set_rate(RATE desc, int speed) {..} void set_clock_src1(SRC_1 desc, string lo_ref){...} void set_clock_src2(SRC_2 desc, string hi_ref) {...} } output_buffer = new OutputFrame(); while (true) { receive( (immutable (float) [] smpls) { add_to_buffer(smpls); output_data(); }, output_buffer.set_rate, output_buffer.set_clock_src1, output_buffer.set_clock_src2, ); } On 27/09/2010 20:49, Juanjo Alvarez wrote: On Mon, 27 Sep 2010 21:00:48 +0200, Johannes Pfau wrote: On 27.09.2010 20:46, Juanjo Alvarez wrote: I'm new to the language so I don't know if this is horribly wrong on some levels, but it works: - import std.variant; import std.stdio; class C { bool test(int i, char c) { writeln(Hello from test1); return true; } void test2(string v) { writeln(Hello from test2, , v); } } void main() { auto c = new C; Variant[string] holder = [test: Variant(c.test), test2: Variant (c.test2)]; receiver(holder); } void receiver(Variant[string] message) { // If you get the Variant template instantiation delegate // signature wrong, it will // be detected at compile time! auto t = message[test].get!(bool delegate(int, char)); auto t2 = message[test2].get!(void delegate(string)); t(1, 'c'); t2(foo); } -- Curiously if you create holder like this, it will give an arrayoutofbound error at runtime, I don't know if that is a bug: void main() { auto c = new C; Variant[string] holder; holder[test] = Variant(c.test); holder[test2] = Variant(c.test2); } I totally forgot about Variant! As far as I know that's exactly what variant is for and it's way better than my proposed hack. The example you posted is perfectly fine as well. I'm not sure what causes the arrayoutofbound error, the second example is correct as well. Yep, variants are cool. You could even use an struct as value type of the associative array and store the variant in one member and the signature of the delegate, as string, in another member. The you could use a mixin in the receiver to extract the delegate without knowing the original signature. All this is wonderfully disturbing to me :)
Re: Dispatching from receive to a function
On Mon, Sep 27, 2010 at 21:49, Juanjo Alvarez juan...@thatwebmailofgoogleproperty.com wrote: Curiously if you create holder like this, it will give an arrayoutofbound error at runtime, I don't know if that is a bug: I think I got this one too. IIRC, it's a bug in the holder[test] part than the Variant(c.test) part. Yep, variants are cool. You could even use an struct as value type of the associative array and store the variant in one member and the signature of the delegate, as string, in another member. The you could use a mixin in the receiver to extract the delegate without knowing the original signature. All this is wonderfully disturbing to me :) I'm not sure you can. You can only mixin strings known at compile-time. Your string member will only have a value at runtime. Except if the struct is an enum, maybe. Philippe
Re: intrusive linked list
That's called intrusive linked list, and I find using it quite viable: zero-allocation O(1) add/removal is a very strong characteristics. They are very useful especially for lock-free algorithms. That's for the info Denis. I got the idea from a friend who is interested in how to make games.