expose class declared in unittest

2014-06-25 Thread rcor via Digitalmars-d-learn
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

2014-06-25 Thread rcor via Digitalmars-d-learn
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

2014-06-25 Thread rcor via Digitalmars-d-learn

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

2014-08-27 Thread rcor via Digitalmars-d-learn

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

2014-08-27 Thread rcor via Digitalmars-d-learn

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

2014-09-01 Thread rcor via Digitalmars-d-learn
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

2014-09-01 Thread rcor via Digitalmars-d-learn
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?

2014-09-04 Thread rcor via Digitalmars-d-learn

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?

2014-09-04 Thread rcor via Digitalmars-d-learn
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?

2014-09-05 Thread rcor via Digitalmars-d-learn
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?

2014-09-05 Thread rcor via Digitalmars-d-learn

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

2014-09-10 Thread rcor via Digitalmars-d-learn
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

2014-09-10 Thread rcor via Digitalmars-d-learn
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

2014-09-10 Thread rcor via Digitalmars-d-learn

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

2014-09-11 Thread rcor via Digitalmars-d-learn

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

2014-09-15 Thread rcor via Digitalmars-d-learn
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

2014-09-15 Thread rcor via Digitalmars-d-learn

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

2014-09-15 Thread rcor via Digitalmars-d-learn

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

2014-09-16 Thread rcor via Digitalmars-d-learn

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

2014-09-16 Thread rcor via Digitalmars-d-learn

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

2014-09-16 Thread rcor via Digitalmars-d-learn

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

2014-10-19 Thread rcor via Digitalmars-d-learn
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

2014-10-20 Thread rcor via Digitalmars-d-learn

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

2014-10-20 Thread rcor via Digitalmars-d-learn
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?

2014-11-09 Thread rcor via Digitalmars-d-learn
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.