expose class declared in unittest
I'm trying to create a set of utility functions that cache objects of various types loaded from json files, but having trouble testing it. One function I'd like to test uses new to instantiate an object based on a compile-time parameter: void loadDataFile(T)(string filename) { ... T obj = new T(name, value); ... } When testing, I try to create a dummy class to test that data can be written and read properly: unittest { class Dummy { ... } ... write some json to a tempfile ... loadDataFile!Dummy(tempfile_path); ... verify loaded data ... } When running the test, I get the error outer function context of util.jsondata.__unittestL31_1 is needed to 'new' nested class util.jsondata.__unittestL31_1. So it seems that a class nested in a unittest can't be 'newed' outside of the test. The test runs if I declare Dummy outside of the unittest, but I don't want it to exist outside of the test. I could import modules containing some of the classes that I will actually be loading with this, but I feel like the unittest shouldn't depend on those, as its designed to work with arbitrary classes. Any suggestions would be appreciated.
Re: expose class declared in unittest
I don't completely understand your problem, but have you tried marking the class as static? static class Dummy { ... } I was about to post links to the actual code to make it more clear, but that did the trick. Thanks for the fast reply. Just to make sure - given: unittest { static class Dummy { ... } } Dummy will not exist unless compiled with -unittest, correct?
Re: expose class declared in unittest
On Wednesday, 25 June 2014 at 20:25:50 UTC, rcor wrote: Dummy will not exist unless compiled with -unittest, correct? Never mind, just verified that this is true. Thanks again.
Issue with dmd 2.066, alias this, and sort
I've tried to express my problem in a mostly minimal example here: https://gist.github.com/murphyslaw480/d4a5f857a104bcf62de1 The class Point has an alias this to its own property 'feature()', which returns a reference to a private member. When I try to sort a Point[], DMD fails with mutable method feature is not callable on const object. I'm not actually using the property 'feature()' or the alias this in the sorting, so it seems like it shouldn't interfere. That being said, I'm still slightly const-challenged so maybe its an error on my part. However, the above example compiles fine with DMD 2.065.0-3.
Re: Issue with dmd 2.066, alias this, and sort
On Wednesday, 27 August 2014 at 21:43:40 UTC, bearophile wrote: It compiles if you use: @property auto feature() const pure nothrow { return _feature; } Otherwise I get strange errors like: ...\dmd2\src\phobos\std\exception.d(986,31): Error: pure function 'std.exception.doesPointTo!(Point, Point, void).doesPointTo' cannot call impure function 'temp.Point.feature' Bye, bearophile Thanks bearophile, that does make the gist compile. However, in my own code, I'm getting all sorts of complaints from other modules about mutable methods not being callable on const objects (the alias this surfaces some methods that are mutable). I guess its my own fault for not being diligent about const-correctness, but it seems odd that sort would care about the constness of feature() when it is sorting based on x and y. Do you know if there is a reason for this?
Re: Programming a Game in D? :D
Just wanted to point out that there are also D bindings for Allegro5 (https://github.com/SiegeLord/DAllegro5). Allegro is a bit like SDL or SFML, but personally I find it a bit more intuitive. I've been using the D bindings for about a month and they seem to work fine. Most Allegro tutorials are for C/C++, but they're not too hard to translate -- all of the allegro functions/structs work almost identically in D as they do in C.
Re: Programming a Game in D? :D
Also, regarding comments about Garbage Collection -- yes, it could be an issue, but its not a showstopper. C# (which has a GC) was widely used to create PC and 360 games with the XNA library (which lives on as MonoGame). If you have a real time game that manages many objects at once, you may have to be careful about allocating/freeing resources and resort to methods like object pooling (reusing objects rather than destroying them and creating new ones), but it should be doable.
Intended behavior of std.range.cycle?
auto c = cycle([1,2,3]); foreach(i ; iota(-4,4)) { writeln(c[i]); } prints the sequence 1 2 3 1 1 - c[0] == c[-1] 2 3 I understand this is what would happen if I were to just use modulus on an index to access the original array, but should Cycle really mimic this behavior? I feel like most uses of Cycle would expect element -1 to be the last element of the original range, not the first. I could manually apply addition with modulus to ensure that the index is always positive, but then there's not much benefit to using cycle anyways -- I might as well be accessing the original range. Is this behavior intentional or an oversight?
Re: Intended behavior of std.range.cycle?
On Thursday, 4 September 2014 at 11:58:58 UTC, monarch_dodra wrote: On Thursday, 4 September 2014 at 11:43:28 UTC, monarch_dodra wrote: Indexing is done with the unsigned size_t. I re-read your post, and I don't think I actually answered your question...? I don't know of any case where you'd want to index negativelly. That said, I'm sure it could be possible to wrap a cycle into a simple signed cycle adaptor. There's one issue with what you want to do though: Who is front, and where does your range start? To give more detail: I've been working on a strategy game. The player has 'next' and 'previous' buttons they can use to cycle between units they haven't moved yet. I thought it would be cleaner to use a Cycle than to have the extra math necessary to wrap the index (its not that the math is terribly complicated, but it just makes things messier and less obvious). In this case, front is arbitrarily chosen based on the order in which the units were loaded. It doesn't really matter who is front as long as each press of 'next' or 'previous' jumps to a new unit. The negative index occurs when the player has unit 0 selected and presses 'previous'. Instead of jumping to the previous unit, the cursor sticks on the same unit (at least in the situation where size_t.max % numUnits == 0). It's not a huge deal to work around it in my own code, but I figured I should point it out in case this was unintentional.
DList.linearRemove on last element -- returned range is non-empty?
According to the docs, linearRemove on a DList returns A range spanning the remaining elements in the container that initially were right after r (http://dlang.org/library/std/container/DList.linearRemove.html) This seems to work fine except when I want to remove the last element. I would expect to get an empty range, as there are no elements following the removed element. Instead, I get a non-empty range (referencing un-initialized memory? Example: auto list = DList!int([1,2,3,4,5]); auto r = list[].drop(4); // r is a view of the last element of list assert(r.front == 5 r.walkLength == 1); r = list.linearRemove(r.take(1)); assert(r.empty); // fails As to why this is an issue: I'm trying to create a list that lazily removes flagged elements. I expect to make frequent removals from arbitrary points in the list. Rather than walking the list to find an element I want to remove, I flag elements for removal. During the next iteration of the list, the range skips over and removes elements that are flagged. This fails when the last element is flagged for removal -- because the range returned by linearRemove is non-empty I'm not aware that I just removed the last element and continue trying to pop elements. You can see a Gist here: https://gist.github.com/murphyslaw480/53869a32402ba1fe5621 I mention this because I may be going about this all wrong, and shouldn't be using linearRemove like this at all. However, I wanted a linear data structure that allowed me to efficiently remove arbitrary elements without relocating whole chunks of arrays.
Re: DList.linearRemove on last element -- returned range is non-empty?
On Friday, 5 September 2014 at 17:17:54 UTC, monarch_dodra wrote: I actually noticed this in code yesterday. Could you please file it? I'll get to fixing it, I'm working on DList right now. https://issues.dlang.org/show_bug.cgi?id=13425 Thanks, its impressive how fast you respond to these posts.
DUB: link to local library
I'd like to link to DAllegro5, which doesn't have an official dub package yet. My project structure looks like this: -- ext/ dallegro5/ allegro5/ d bindings that need to be imported libdallegro5.a -- library I need to link to src/ app.d single source file which uses DAllegro5 bindings dub.json -- app.d is just the DAllegro5 example: https://github.com/SiegeLord/DAllegro5/blob/master/example.d I can build a working executable with the following command: dmd -Iext/dallegro5 -L-Lext/dallegro5 src/app.d dub.json contains what I think should do the same as above: { name: test, importPaths: [ext/dallegro5], lflags: [-Lext/dallegro5] } Obviously this is missing some fields that I would want in a full project like authors and license but I'm trying to keep it simple until I figure out dub. dub.json seems like it should add the import and library search paths just like the dmd command I used, but instead fails with linker errors: .dub/build/application-debug-linux.posix-x86_64-dmd-323FC98A6F20DD1891F81CB0FEE1D200/test.o:(.rodata+0x1ba8): undefined reference to `_D8allegro57allegro12__ModuleInfoZ' ... a few more of these, followed by: .../test/src/app.d:39: undefined reference to `al_init' ... and many more undefined references Does anyone have an idea of how to make this work? I can push this test project structure up on a git repo if it would help to see the whole thing.
Re: DUB: link to local library
On Wednesday, 10 September 2014 at 15:40:11 UTC, Edwin van Leeuwen wrote: On Wednesday, 10 September 2014 at 13:40:16 UTC, rcor wrote: dub.json contains what I think should do the same as above: { name: test, importPaths: [ext/dallegro5], lflags: [-Lext/dallegro5] } Does adding: libs: [dallegro5] make a difference? Cheers, Edwin I thought libs was for linking to system libraries, which dallegro5 isn't (its just built locally and not installed system-wide). However, libs: [dallegro5] does seem to change the errors a bit: Without: http://pastebin.com/Xpq94EkR With: http://pastebin.com/7fet3xU1 In particular, it makes the undefined reference to al_init disappear, so maybe its a step in the right direction. Allegro divides its functionality into several modules -- when I was using C I would have to specify each of these libs, which I would get from pkgconfig. I wonder if I need to do that here, but it wasn't necessary when I was building with dmd alone.
Re: DUB: link to local library
On Wednesday, 10 September 2014 at 16:26:07 UTC, andre wrote: Dub command line supports something like Dub add-local. Then you can use the package directly. Kind regards Andre DAllegro5 doesn't have an official dub package yet, but I threw together one that could build the library and added it with `dub add-local`. It now shows up in `dub list`, but adding: dependencies: { dallegro5: ~master } doesn't seem to change anything. I think the dub.json I put in dallegro5 works, because the library it produces can be used to run the example with dmd.
Re: DUB: link to local library
Finally got it: { name: test, importPaths: [ext/dallegro5], lflags: [-Lext/dallegro5], libs: [ allegro, allegro_acodec, allegro_audio, allegro_font, allegro_ttf, allegro_image, allegro_color, allegro_primitives ], dependencies: { dallegro5: ~master } } I had to specify the C libs for allegro and its addons. Also, specifying dallegro5 as a dependency does seem to be necessary (this is after adding with `dub add local`). Thanks for all the suggestions.
Segfault when casting array of Interface types
I'm back for another round of is this a bug, or am I doing something stupid?. C and D implement interface I, and I have an array of each. I'd like to combine these into one I[], but eventually I'd like to cast an element back to its original type. interface I {} class C : I {} class D : I {} void main() { C[] c = [new C, new C]; D[] d = [new D, new D]; auto i = cast(I[]) c ~ cast(I[]) d; assert(cast(C) i[0]); // segfault } casting each array to I[] is fine, but casting an element back to C segfaults (even if it weren't a C, it should just return null, right?)
Re: Segfault when casting array of Interface types
On Tuesday, 16 September 2014 at 03:05:57 UTC, Franz wrote: Your issue comme from auto. i is a I[] I expected i to be an I[], but shouldn't a casting an element of an I[] to a C return either a C or null? It is if I do this: I[] i = [cast(I) new C, new D]; assert(cast(C) i[0]); // fine Come to think of it, the above will probably work in my situation. But I still wonder why the first example doesn't work.
Re: Segfault when casting array of Interface types
seemingly even weirder: I[] i0 = [new C, new C]; assert(cast(C) i0[0]); // fine C[] c = [new C, new C]; I[] i1 = cast(I[]) c; assert(cast(C) i1[0]); // fails It works when I create an I[] from a C[] literal, but not when I cast a previously declared C[] to an I[].
Re: Segfault when casting array of Interface types
On Tuesday, 16 September 2014 at 08:49:04 UTC, Marc Schütz wrote: On Tuesday, 16 September 2014 at 08:39:43 UTC, Marc Schütz wrote: Whether the compiler should accept that or not is a different question. I guess it should, because if it doesn't, there wouldn't be an easy way to achieve a reinterpret cast (only via an intermediate cast to `void*`, which is clumsy). Anyway, using `std.conv.to` is the way to go here (if you don't require that last bit of performance), because it is safer in general (also checks for overflows and the like, for example). Thanks, didn't think of trying std.conv.to. Can someone expand a bit on what to! is doing in this situation that cast isn't? I looked up 'reinterpret cast' but didn't see the connection to this. AFAIK casting between interfaces and classes needs to adjust the underlying pointer. Therefore, when casting an array, the compiler would have to do that with the entire array, which cannot be copied without allocating memory (and mustn't be modified in-place for consistency reasons). This means that the cast is instead a pure reinterpret cast (repainting). Is to! creating a new array of pointers while cast isn't? This isn't a performance critical section and it's not a huge array, so I ask mostly out of curiosity.
Re: Segfault when casting array of Interface types
On Tuesday, 16 September 2014 at 06:27:59 UTC, Klaus wrote: is just a horrible way of shortcuting the static typing. You write this thinking that i has to be... and then you complain latter because the cast does not work. D is a strongly typed lang. in your example you use auto because your brain doesnt give you what the type of i has to be, which is an error. D is not a scripting lang. You made a wrong usage of auto. Admittedly this came about as a result of some poor design on my part, but I don't get what you're saying about auto. I thought auto was supposed to relieve the cognitive load of manual type identification. Without it, std.algorithm would be a pain to use. My brain doesn't intuitively tell me that std.algorithm.filter returns a FilterResult, but I can use it effectively with auto.
Re: Segfault when casting array of Interface types
On Tuesday, 16 September 2014 at 14:13:48 UTC, Marc Schütz wrote: On Tuesday, 16 September 2014 at 11:26:05 UTC, rcor wrote: Is to! creating a new array of pointers while cast isn't? This isn't a performance critical section and it's not a huge array, so I ask mostly out of curiosity. Yes, it is. (Probably. I don't have the time to test it now, but it's likely if my theory about the pointer adjustment is correct.) I guess I could have checked that out myself: import std.stdio; import std.conv; interface I {} class C : I {} class D : I {} void main() { C[] c = [new C, new C]; I[] i = cast(I[]) c; I[] i2 = c.to!(I[]); assert(c is cast(C[]) i);// i and c point to same address assert(i !is i2);// to! appears to create a new array }
Base class with member parameterized on type of extending class
I'm trying to make a game, and would like to set up the following hierarchy: At any time, the game is in one Scene. Each scene has a state machine that manages States of type T, where T is the type of the scene (e.g. Overworld, Menu). abstract class State!T { void update(T scene, float time, InputManager input); ... } class StateMachine!T { //manages states of type State!T } abstract class Scene { alias T = // type of class extending Scene // methods pushState, popState, currentState access _stateMachine private StateMachine!T _stateMachine; } class MainMenu : Scene { // I want _stateMachine of type StateMachine!MainMenu } class Overworld : Scene { // I want _stateMachine of type StateMachine!Overworld } class MoveToLocation : State!Overworld { override void update(Overworld world, float time, InputManager input) { // access properties of Overworld here } } Within the Scene class, I've tried alias T = typeof(this), but that appears to be resolved within Scene. This means that any Scene, such as Overworld, have a state machine of type StateMachine!Scene rather than StateMachine!Overworld. Since States are particular to a certain scene and are designed to manipulate properties specific to that type of scene, this would involve a lot of casting if States are not parameterized. It feels like I need something like a class version of the (this T) syntax used in templates. This all smells a bit off though, so I wouldn't be surprised if the answer is that I'm approaching this all wrong, but right now I'm not seeing it.
Re: Base class with member parameterized on type of extending class
On Monday, 20 October 2014 at 06:17:42 UTC, Jacob Carlborg wrote: You can always make Scene a template class: abstract class Scene (T) { private StateMachine!T _stateMachine; } class MainMenu : Scene!(MainMenu) {} But I'm guessing you like to avoid that if possible. I would, as I need to keep track of the current scene in a variable somewhere: Scene _currentScene; // problematic if Scene is a template I could just declare the StateMachine separately in every Scene, but that seems like a lot of duplicate code (I then repeat the same code for updating the state machine, ect.)
Re: Base class with member parameterized on type of extending class
If the state machine doesn't need to be exposed you can create base class for Scene which is not templated: abstract class Scene {} // As it is now minus the state machine abstract class ConcreteScene (T) : Scene { private StateMachine!T _stateMachine; // other code that need access to _stateMachine } class MainMenu : ConcreteScene!(MainMenu) {} Scene _currentScene = new MainMenu; ConcreteScene might not be the best name of an abstract class. Just came up with something similar before I saw this post: interface IScene { // enter, exit, update, draw } class Scene!T : IScene { private StateMachine!T _stateMachine; void update(float time) { _stateMachine.update(cast(T) this, time); } } The cast is unfortunate but since it only happens once per update cycle I'm not that worried about it. I could just declare the StateMachine separately in every Scene, but that seems like a lot of duplicate code (I then repeat the same code for updating the state machine, ect.) Or you could use a template mixin: template StateMachineMixin (T) { private StateMachine!T _stateMachine; // other code that need access to _stateMachine } class MainMenu : Scene { mixin StateMachineMixin!(typeof(this)); } Interesting idea, I might give this a try but the first suggestion seems fine for now. Thanks!
Re: Live without debugger?
On Sunday, 9 November 2014 at 09:14:14 UTC, ketmar via Digitalmars-d-learn wrote: On Sun, 09 Nov 2014 08:26:57 + Suliman via Digitalmars-d-learn digitalmars-d-learn@puremagic.com wrote: Do you often need debugger when you are writing code? almost never. For which tasks debugger are more needed for you? inspecting coredumps. Pretty much this for me too. I wish I could make more use of it, but the best debugger I've found is GDB, which still seems far from optimal for D. It can at least give you an idea of where the core dump was triggered.