Re: Initalizing complex array types or some other problem ;/

2015-09-15 Thread Prudence via Digitalmars-d-learn

On Tuesday, 15 September 2015 at 20:54:49 UTC, anonymous wrote:

On Tuesday 15 September 2015 22:09, Prudence wrote:


The code below doesn't work.


Please be more specific in how it doesn't work. Mention the 
error message if there is one, or say how the code behaves 
differently from what you'd expect.


Trying to compile the code (after kicking getch out), I get 
this error:

core.exception.RangeError@test.d(103): Range violation

Line 103 is: writeln(MyStore.Store[k].length);

I can't find where you set Store[k]. Maybe you forgot that or 
deleted it accidentally?


I made a guess and added this line in SingleStore.New:
o.Store[k] ~= tuple(v, o);

It still throws a range error with this. That's because 
associative arrays are a little weird, unfortunately.


An AA is effectively initialized on the first assignment. So 
(with my addition) the first SingleStore.New call initializes 
the AA. But it only initializes o.Store, not the original 
variable s (i.e. ObjectStore.Store). s is left empty.


Possible solutions/workarounds:
* Append to s[k], then assign s to o.Store.
* Initialize ObjectStore.Store in a static constructor:

static this()
{
Store[TKey.init] = [];
Store.remove(TKey.init);
}


Maybe. Seems to work without it. The code below should compile on 
your system and work(and prints 1 2 3 4, 4 3 2 1). The getch is 
required on windows if I want to see the output, so I don't know 
why you even bothered mention replacing it.






import std.stdio;
import std.concurrency;



extern (C) int getch();
import std.string;
import std.concurrency;
import core.time;
import core.thread;
import std.container.array;
import std.typecons;







public class SingleStore(TKey, TValue)
{
public TValue Value;
public TKey Key;
public Tuple!(TValue, SingleStore!(TKey, TValue))[][TKey] Store;


	// Duplicate entries will be removed together as there is no way 
to distinguish them

public auto Remove()
{
import std.algorithm;
if (Value == null || Key == null) return;
int count = 0;
for(int i = 0; i < Store[Key].length; i++)
{
if (Store[Key][i][0] == Value && Store[Key][i][1] == 
this)
{
count++;
	Store[Key][i] = tuple(null, null); // Set to null to release 
any references if necessary
	swap(Store[Key][i], Store[Key][max(0, Store[Key].length - 
count)]);

i = i - 1;
}

}
if (count == 1 && Store[Key].length == 1)
{
Store[Key] = null;
Store.remove(Key);
} else
//Store[Key] = 
Store[Key][0..max(0,Store[Key].length-count)];
Store[Key].length = Store[Key].length - count;

Value = null;
Key = null;

}

	public static auto New(TKey k, TValue v, ref Tuple!(TValue, 
SingleStore!(TKey, TValue))[][TKey] s)

{
auto o = new SingleStore!(TKey, TValue)();  // GC
o.Key = k;
o.Value = v;
s[k] ~= tuple(v, o);
o.Store = s;

return o;
}

}


// Creates a static Associative Array that stores multiple values 
per key. The object returned by New can then be used to remove 
the key/value without having to remember specifically them.

public mixin template ObjectStore(TKey, TValue)
{
	// The object store. It is static. Mixin the template into it's 
different types to create different types of stores. All objects 
of that type are then in the same store.
	public static Tuple!(TValue, SingleStore!(TKey, TValue))[][TKey] 
Store;


public static auto New(TKey k, TValue v)
{
auto r =  SingleStore!(TKey, TValue).New(k, v, Store);
return r;
}

}

//alias dg = int delegate(int);
alias dg = string;

public class cMyStore(TKey, TValue)
{
//mixin ObjectStore!(string, dg);
mixin ObjectStore!(string, string); 
}



void main()
{
alias MyStore = cMyStore!(string, string);
auto k = "x";

auto r = 

/*
dg d1 = (int x) { return x; };
dg d2 = (int x) { return x; };
dg d3 = d1;
dg d4 = (int x) { return 3*x; };
*/

dg d1 = "a1";
dg d2 = "a2";
dg d3 = "a3";
dg d4 = "a4";



auto s = MyStore.New(k, d1);
writeln(MyStore.Store[k].length);
auto s1 = MyStore.New(k, d2);
writeln(MyStore.Store[k].length);
auto s2 = MyStore.New(k, d3);
writeln(MyStore.Store[k].length);
auto s3 = MyStore.New(k, d4);
writeln(MyStore.Store[k].length);   


//auto x = MyStore.Store[k][0](3);
  

Initalizing complex array types or some other problem ;/

2015-09-15 Thread Prudence via Digitalmars-d-learn
How does one initialize a tuple type and are arrays initialized 
by default?



The code below doesn't work. I recently converted to use a tuple 
and that seemed to have broke it and I don't know why, when I 
changed the New function to use a ref, that made it worse cause 
now the array is all ways null. Debugging doesn't help much 
because, for some reason, VD won't show object information inside 
the mixin ObjectStore.



	alias StoreType = Tuple!(TValue, SingleStore!(TKey, 
TValue))[][TKey];

public static StoreType Store;

I thought using the alias would help but it doesn't. Trying to 
init it in the static this doesn't seem to help me, as I can't 
get it to new propertly. e.g., new StoreType(); fails.


Any ideas?






import std.stdio;
import std.concurrency;



extern (C) int getch();
import std.string;
import std.concurrency;
import core.time;
import core.thread;
import std.container.array;
import std.typecons;







public class SingleStore(TKey, TValue)
{
public TValue Value;
public TKey Key;
public Tuple!(TValue, SingleStore!(TKey, TValue))[][TKey] Store;


public auto Remove()
{
import std.algorithm;
if (Value == null || Key == null) return;
int count = 0;
for(int i = 0; i < Store[Key].length; i++)
{
if (Store[Key][i][0] == Value && Store[Key][i][1] == 
this)
{
count++;
Store[Key][i] = tuple(null, null);
	swap(Store[Key][i], Store[Key][max(0, Store[Key].length - 
count)]);

i = i - 1;
}


}
if (count == 1 && Store[Key].length == 1)
{
Store[Key] = null;
Store.remove(Key);
} else
//Store[Key] = 
Store[Key][0..max(0,Store[Key].length-count)];
Store[Key].length = Store[Key].length - count;

Value = null;
Key = null;

}

	public static auto New(TKey k, TValue v, ref Tuple!(TValue, 
SingleStore!(TKey, TValue))[][TKey] s)

{
auto o = new SingleStore!(TKey, TValue)(k, v);  // GC
o.Store = s;
return o;
}

private this(TKey k, TValue v)
{
Key = k;
Value = v;
}
}


// Creates a static Associative Array that stores multiple values 
per key. The object returned by New can then be used to remove 
the key/value without having to remember them specifically.

public mixin template ObjectStore(TKey, TValue)
{
	alias StoreType = Tuple!(TValue, SingleStore!(TKey, 
TValue))[][TKey];

public static StoreType Store;

public static auto New(TKey k, TValue v)
{
auto r =  SingleStore!(TKey, TValue).New(k, v, Store);
return r;
}
}

alias dg = int delegate(int);

class MyStore
{
mixin ObjectStore!(string, dg);
}

void main()
{

auto k = "x";

dg d1 = (int x) { return x; };
dg d2 = (int x) { return x; };
dg d3 = d1;
dg d4 = (int x) { return 3*x; };

auto s = MyStore.New(k, d1);
writeln(MyStore.Store[k].length);
auto s1 = MyStore.New(k, d2);
writeln(MyStore.Store[k].length);
auto s2 = MyStore.New(k, d3);
writeln(MyStore.Store[k].length);
auto s3 = MyStore.New(k, d4);
writeln(MyStore.Store[k].length);   

s1.Remove();
writeln(MyStore.Store[k].length);
s2.Remove();
writeln(MyStore.Store[k].length);
s.Remove();
writeln(MyStore.Store[k].length);
s3.Remove();



getch();
}


Convert array to tupled array easily?

2015-09-14 Thread Prudence via Digitalmars-d-learn
I created the following code that some of you have already seen. 
It's sort of a multiple value AA array with self tracking.


The problem is, that for some type values, such as delegates, the 
comparison is is identical. (basically when the delegate is the 
same)


To solve that problem, I'd like to try and turn the Value into 
Tuples of the Value and the address of the SingleStore 
wrapper(which should be unique).


e.g.,
public Tuple!(TValue, void*)[][TKey] Store;

then I'll simply compare the value and address stored with the 
this(inside single store) instead of just this.


Of course, this requires somewhat of a rewrite of the code(trying 
it produced all kinds of errors(I tried to fix up all the 
references and correlated variables but still a mess, specially 
with D's error codes).


It shouldn't be that much trouble though. Essentially where ever 
I access the value, I want to instead of use value from the 
tuple(a single indirection).


Probably not that easy though?



import std.stdio;
import std.concurrency;



extern (C) int getch();
import std.string;
import std.concurrency;
import core.time;
import core.thread;
import std.container.array;
import std.typecons;







public class SingleStore(TKey, TValue)
{
public TValue Value;
public TKey Key;
public TValue[][TKey] Store;


	// Duplicate entries will be removed together as there is no way 
to distinguish them

public auto Remove()
{
import std.algorithm;
if (Value == null || Key == null) return;
int count = 0;
for(int i = 0; i < Store[Key].length;i++)
{
auto c = Store[Key][i];
if (c == Value)
{
count++;
	Store[Key][i] = null; // Set to null to release any 
references if necessary
	swap(Store[Key][i], Store[Key][max(0, Store[Key].length - 
count)]);

i = i - 1;
}


}
if (count == 1 && Store[Key].length == 1)
{
Store[Key] = null;
Store.remove(Key);
} else
Store[Key] = 
Store[Key][0..max(0,Store[Key].length-count)];

Value = null;
Key = null;

}

public static auto New(TKey k, TValue v, ref TValue[][TKey] s)
{
auto o = new SingleStore!(TKey, TValue)(k, v);  
o.Store = s;
return o;
}

private this(TKey k, TValue v)
{
Key = k;
Value = v;
}
}


// Creates a static Associative Array that stores multiple values 
per key. The object returned by New can then be used to remove 
the key/value without having to remember specifically them.

public mixin template ObjectStore(TKey, TValue)
{
	// The object store. It is static. Mixin the template into it's 
different types to create different types of stores. All objects 
of that type are then in the same store.

public static TValue[][TKey] Store;

public static auto New(TKey k, TValue v)
{
(Store[k]) ~= v;
auto o = SingleStore!(TKey, TValue).New(k, v, Store);
return o;
}

public string ToString()
{
return "asdf";
}


}

alias dg = int delegate(int);
//alias dg = string;

class MyStore
{
mixin ObjectStore!(string, dg);
//mixin ObjectStore!(string, string);

}

void main()
{

auto k = "x";


dg d1 = (int x) { return x; };
dg d2 = (int x) { return x; };
dg d3 = d1;
dg d4 = (int x) { return 3*x; };

/*
dg d1 = "a1";
dg d2 = "a2";
dg d3 = "a3";
dg d4 = "a4";
*/


auto s = MyStore.New(k, d1);
writeln(MyStore.Store[k].length);
auto s1 = MyStore.New(k, d2);
writeln(MyStore.Store[k].length);
auto s2 = MyStore.New(k, d3);
writeln(MyStore.Store[k].length);
auto s3 = MyStore.New(k, d4);
writeln(MyStore.Store[k].length);   

//auto x = MyStore.Store[k][0](3);
//writeln("-" ~ x);

s1.Remove();
writeln(MyStore.Store[k].length);
s2.Remove();
writeln(MyStore.Store[k].length);
s.Remove();
writeln(MyStore.Store[k].length);
s3.Remove();



getch();
}


Re: shared array?

2015-09-13 Thread Prudence via Digitalmars-d-learn
On Sunday, 13 September 2015 at 16:58:22 UTC, Ola Fosheim Grøstad 
wrote:
On Sunday, 13 September 2015 at 15:35:07 UTC, Jonathan M Davis 
wrote:
the GC heavily. And the reality of the matter is that the vast 
majority of programs will have _no_ problems with using the GC 
so long as they don't use it heavily. Programming like you're 
in Java and allocating everything on the heap will kill 
performance, but idiomatic D code doesn't do that, and Phobos 
doesn't do that. Far too many programmers freak out at the 
thought of D even having a GC and overreact thinking that they 
have to root it out completely, when there really is no need 
to. Plenty of folks how written highly performant code in D 
using the GC. You just have to avoid doing a lot of allocating 
and make sure you track down unwanted allocations when you 
have a performance problem.


I don't understand this argument. Even if the GC heap only 
contains a single live object, you still have to scan ALL 
memory that contains pointers.


So how does programming like you do in Java affect anything 
related to the GC?


Or are you saying that finalization is taking up most of the 
time?


The problem is that these people arguing that the GC is the holy 
grail simply use statistics for their reasoning. They pigeon 
everyone in the same box they exist in, and you find out it's 
useless to argue with them because their logic is flawed.


What if I happen to write a RT app that happens to use a part of 
phobo's that happens to heavily rely on the GC? Am I suppose to 
use -vgs all the time to avoid that? Do I avoid phobo's because 3 
functions in it use the GC? Am I suppose to memorize a table of 
all the places phobo's uses the GC and then roll my own to avoid 
them?


The fact is, that the proponents of the GC such as JMD do not 
write RT apps and could care less bout that aspect. This is why 
they make such easy claims. For them, RT is just theoretical 
mumbo jumbo that doesn't exist in the real world. The GC is, 
also, for them, a safety blanket so they can be lazy and not have 
to keep track of all the things they should be. This type of 
mentality seems to run rampet in the contributors of D. They 
simply cannot understand the perspective of the other side(or 
refuse to).


Statistics has nothing to do with facts. The fact is, for a hard 
real time app, the GC and it's stop the world behavior is a no 
go. As long as the mentality exists that the GC is good enough 
because it 99% of phobo's doesn't use it or 99% of apps don't 
need RT, or whatever, D will never be as powerful as it can be.


Basically, I know you need your snotty safety blanket and it 
works for you, but I don't want to use it! Don't force me! I 
won't force you to give up your blanket but don't force me to use 
it. The road goes both ways, stop trying to make it one way.
(The argument is fundamentally different. They want to exclude, I 
want to include)


Of course, the real issue is, that it will take someone that has 
the opposite point of view from them to actually do anything 
about it, because it's obvious they won't work the direction they 
think is a waste. So, ultimately, it's people like me that have 
to step up and actually do the work. I am hesitant because it's 
always an uphill battle with such people. Instead of working 
together, they have to make it a struggle. (it's always "Why are 
you trying to take my safety blanket away!!! wa, wa wa" and tears 
follow)










Re: shared array?

2015-09-13 Thread Prudence via Digitalmars-d-learn

On Sunday, 13 September 2015 at 17:16:02 UTC, ponce wrote:
On Sunday, 13 September 2015 at 17:00:30 UTC, Ola Fosheim 
Grøstad wrote:

On Sunday, 13 September 2015 at 16:53:20 UTC, ponce wrote:
GC is basically ok for anything soft-realtime, where you 
already spend a lot of time to go fast enough. And if you 
want hard-realtime, well you wouldn't want malloc either.


It's a non-problem.


If this was true then Go would not have a concurrent collector.


I was speaking of the D language.


Of course, that makes it make sense!


Re: Mixin templates accessing mixed out scope

2015-09-12 Thread Prudence via Digitalmars-d-learn

On Saturday, 12 September 2015 at 17:11:04 UTC, anonymous wrote:

On Saturday 12 September 2015 16:30, Ali Çehreli wrote:


Reduced:

[...]

Error: type SingleStore is not an expression


Reduced further:


class MyStore
{
class SingleStore
{
static void New() // Removing 'static' compiles
{
new SingleStore();
}
}
}


And now the problem can be spotted:

SingleStore is a nested class. That means, instances of it are 
bound to MyStore instances. But New is static, so it doesn't 
have a MyStore to which it could attach the `new SingleStore`.


That error message is pretty awful. I filed an issue: 
https://issues.dlang.org/show_bug.cgi?id=15049


like most D errors ;/ it's the #1 problem I'm struggling with in 
D. Remember there's another error with remove, that isn't 
releated to SingleStore.


As for a fix: I guess SingleStore isn't supposed to be a nested 
class. Mark it static then.


NO! That is the whole point!

SingleStore is a momento that wraps the key value pair, e.g.,

auto t = DeleteStore.New("mycooldelegate", (int x) { return true; 
});


t is suppose to be a single store.

then

t.Remove();

removes the delegate from the store.

Note I don't have to know the actual key or delegate!! Which is 
the whole point!


Else it would lool like this:

store[][string] mydelegatestore;

auto dg = (int x) { return true; };
mydelegatestore["mycooldelegate"] ~= dg;

then

mydelegatestore["mycooldelegate"].remove(d => dg == d);

which requires remembering both the key and the delegate, which 
makes using inline lambdas infeasible(because you'll never be 
able to remove them).


I see no reason why SingleStore has to be static. The mixin 
template should insert all that stuff into the class, which, by 
the way, works...


I've also used that New pattern all that time and it works, maybe 
not for nested classes. Moving SingleStore outside the template 
works.




I've fixed the issue with that, it's not as pretty but works. 
Still have the remove error:









import std.stdio;
import std.concurrency;



extern (C) int getch();
import std.string;
import std.concurrency;
import core.time;
import core.thread;
import std.container.array;
import std.typecons;







public class SingleStore(TKey, TValue)
{
public TValue Value;
public TKey Key;
public TValue[][TKey] Store;
public auto Remove()
{
import std.algorithm;
		remove!(c => Value == c")(Store[this.Key], 
SwapStrategy.unstable);	 // Not working, can't disambiguate

}

public static auto New(TKey k, TValue v, ref TValue[][TKey] s)
{
auto o = new SingleStore!(TKey, TValue)(k, v);  
o.Store = s;
return o;
}

private this(TKey k, TValue v)
{
Key = k;
Value = v;
}
}

public mixin template ObjectStore(TKey, TValue)
{
public static TValue[][TKey] store;

public static auto New(TKey k, TValue v)
{
(store[k]) ~= v;
auto o = SingleStore!(TKey, TValue).New(k, v, store);
o.store = store;
return o;
}


}


class MyStore
{
mixin ObjectStore!(string, bool delegate(int));


}

void main()
{
	auto s = MyStore.New("x", (int x) { return true; }); // works, 
stores delegate in MyStore


	s.Remove();  // Doesn't work because std.algorithm's remove 
isn't working


getch();
}

(The whole point of nesting was so I wouldn't have to explicitly 
create a pointer to the store in SingleStore. Should have worked, 
probably another one of D's bugs)








Re: Mixin templates accessing mixed out scope

2015-09-12 Thread Prudence via Digitalmars-d-learn

On Saturday, 12 September 2015 at 14:30:16 UTC, Ali Çehreli wrote:

On 09/12/2015 06:37 AM, Prudence wrote:


Says the creating new SingleStore is not an expression


Reduced:

mixin template ObjectStore(TKey)
{
class SingleStore
{
static void New()// Removing 'static' compiles
{
new SingleStore();
}
}
}

class MyStore
{
mixin ObjectStore!(int);
}

void main()
{
auto s = new MyStore();
}

Error: type SingleStore is not an expression

Ali


Are you saying this is a bug or something else? The only 
alternative I can think of is to use string mixins but this 
method should work?


Does a synchronization yield on waiting thread?

2015-09-12 Thread Prudence via Digitalmars-d-learn

It would seem to be the logical thing to do?

That is, suppose two threads are sharing a resource. Thread A has 
it locked. B is "waiting". Is B in a loop burning cycles running 
in the background(regardless of thread.sleep, which only 
alleviates the problem) or does it yield completely and somehow 
inform the lock to resume it when A has unlocked the resources?


The first one burns cycles and can have timing problems. I.e., 
What if A locks and unlocks at the same rate that B checks? (I 
suppose a random sleep time would help with this) (


"Yielding", OTOH, has B burn no cycles waiting in a loop. This 
can lead to optimization and prioritization and all that(after an 
unlock, all the threads waiting can be called, but in what order).


Obviously yielding is more complex and requires the threads kept 
track of(an array for each lock/unlock pair) but far more 
efficient.


I'm hoping D does this, but not holding my breath.





Re: shared array?

2015-09-12 Thread Prudence via Digitalmars-d-learn
On Saturday, 12 September 2015 at 06:23:12 UTC, Jonathan M Davis 
wrote:
On Friday, September 11, 2015 23:29:05 Laeeth Isharc via 
Digitalmars-d-learn wrote:
On Friday, 11 September 2015 at 21:58:28 UTC, Adam D. Ruppe 
wrote:

> [...]

Seems to be quite a lot of FUD wrt use of standard library and 
GC, which means also perhaps we don't communicate this point 
very well as a community.  Making Phobos GC-optional perhaps 
is an ultimate answer.  But people seem to think that you're 
back to C without the GC.


Aside from the few classes in Phobos, its GC usage is almost 
entirely restricted to when it allocates arrays or when it has 
to allocate a closure for a delegate, which can happen in some 
cases when passing predicates to range-based algorithms. 
Avoiding functions that need to allocate arrays avoids that 
source of allocation, and using functors or function pointers 
as predicates avoids having to allocate closures. So, you _can_ 
end up with GC allocations accidentally in Phobos if you're not 
careful, but on the whole, the assertion that Phobos uses the 
GC heavily is FUD - or at least a misunderstanding. But as we 
make more of the functions use lazy ranges rather than arrays 
(particularly with regards to strings), and we make more of the 
code @nogc, it becomes even clearer that the GC isn't involved. 
Also, improvements to how lambdas are handled should reduce how 
often closures have to be allocated for them.




I don't think it's that simple.

Saying that it doesn't use it most of the time is not an 
answer/solution. Using it at all is a problem because one doesn't 
know when and where. I realize there is a switch now(-vgc), and 
maybe that is the solution, but you say "well, phobos only uses 
0.01% on the GC", yet since you either don't, can't, or won't 
know where that is, then it might as well be 100% if you would 
like to potentially get off the GC one day.


It's like playing Russian roulette. It doesn't matter if only 1/6 
times will kill you. It's totally different than 0/6.






Mixin templates accessing mixed out scope

2015-09-12 Thread Prudence via Digitalmars-d-learn


The following code simply does not work, it might be buggy now 
after fiddling with it but basically remove and the 
SingleStore.New are not working(Says the creating new SingleStore 
is not an expression, which makes no sense to me).



Essentially I'm creating a mixin template so I can have different 
"object stores", which is just an associative array of arrays. 
The SingleStore wraps the key, value pair added to the store so 
that I can keep track of and remove the added object easily 
without having to explicitly remember everything(e.g., what if 
TValue is a delegate? Then it get's messy).


Why remove can't disambiguate is beyond me... Why I can't create 
a SingleStore!(int, double)() is beyond me! It would be nice if 
D's errors were a little more helpful!



Error		Error: type SingleStore!(int, double) is not an 
expression		Test.d	56


auto o = new SingleStore!(TKey, TValue)(k, v);  

huh??? Have I just lost it or is this how one is suppose to 
create such an object?


(I do realize that I do not have to parameterize SingleStore. It 
is irrelevant here though)


import std.stdio;
import std.concurrency;



extern (C) int getch();
import std.string;
import std.concurrency;
import core.time;
import core.thread;
import std.container.array;
import std.typecons;








// Creates a static Associative Array that stores multiple values 
per key. The object returned by New can then be used to remove 
the object without having to remember the object specifically.

public mixin template ObjectStore(TKey, TValue)
{
	// The object store. It is static. Mixin the template into it's 
different types to create different types of stores. All objects 
of that type are then in the same store.

public static TValue[][TKey] store;

public static auto New(TKey k, TValue v)
{
(store[k]) ~= v;
auto o = SingleStore!(TKey, TValue).New(k, v);
return o;
}

public static auto Remove(SingleStore!(TKey, TValue) o)
{
import std.algorithm;
		//remove!(c => (this.Value == c))(store[o.Key], 
SwapStrategy.unstable);

}


public class SingleStore(TKey, TValue)
{
public TValue Value;
public TKey Key;

public auto Remove()
{
import std.algorithm;
			//remove!("c => (this.Value == c)")(store[this.Key], 
SwapStrategy.unstable);

//super.Remove(this);
}

public static auto New(TKey k, TValue v)
{
auto o = new SingleStore!(TKey, TValue)(k, v);  
return o;
}

private this(TKey k, TValue v)
{
Key = k;
Value = v;
}
}

}


class MyStore
{
mixin ObjectStore!(int, double);
}

void main()
{
auto s = new MyStore();


getch();




Re: shared array?

2015-09-11 Thread Prudence via Digitalmars-d-learn

On Friday, 11 September 2015 at 16:04:22 UTC, Kagamin wrote:

On Friday, 11 September 2015 at 14:54:00 UTC, Prudence wrote:
But in this case it is static, so why does it matter? Do you 
have any ideas how to wrap it or fix this?


It matters exactly because it is static. A code written for 
single-threaded environment may not work correctly in shared 
context. It simply wasn't written for it. The way to fix it is 
to write code for shared context.


I don't care about "maybe" working. Since the array is hidden 
inside a class I can control who and how it is used and deal with 
the race conditions.


What I want is to be able to use Array so I don't have to rely on 
the GC. but since it complains about the ~this destruction, how 
can I fix that? If I wrap Array, and use a non-shared array 
inside it, I'll  still have the same problem because it will be 
thread local to the object? or is shared applied to all sub types 
of a class?


e.g.,

class MySharedArrayWrapper
{
static Array!(int) a;

}

and instead I use

static shared MySharedArrayWrapper;

But a isn't marked shared, so will it be TLS, which put's me back 
at square one. Or it it marked shared, which then still complains?


Again, I'm asking how, not why.


Re: shared array?

2015-09-11 Thread Prudence via Digitalmars-d-learn

On Friday, 11 September 2015 at 19:27:49 UTC, Adam D. Ruppe wrote:

On Friday, 11 September 2015 at 17:29:47 UTC, Prudence wrote:
I don't care about "maybe" working. Since the array is hidden 
inside a class I can control who and how it is used and deal 
with the race conditions.


You could use __gshared instead of shared. It means put it in 
non-tls storage, just like shared, but the compiler will not 
attempt to help you use it correctly; you're on your own for 
synchronization, etc.


What I want is to be able to use Array so I don't have to rely 
on the GC.


But, again, built-in slices do NOT rely on the GC. Only 
specific methods on them do and you can use your own 
implementation for them.


Really?

Can you back up this claim? Not saying your lying, I'd just like 
to know it's true for a fact?


Ho wan you use "specific methods"? Do you mean I do not use new 
to allocate and use malloc(more or less)?


In that case, am I not essentially just re-creating Array? 
Obviously I can write my own array type and I can even write my 
own compiler, but that's no that the point, is it?








Re: shared array?

2015-09-11 Thread Prudence via Digitalmars-d-learn

On Friday, 11 September 2015 at 20:30:37 UTC, Adam D. Ruppe wrote:

On Friday, 11 September 2015 at 20:06:53 UTC, Prudence wrote:
Can you back up this claim? Not saying your lying, I'd just 
like to know it's true for a fact?


The list of things that trigger the GC is pretty short. See the 
bottom of this page:


http://dlang.org/garbage.html

Basically, the three things that can do a gc allocation in a 
built in array are: increasing the length, the ~= and ~ 
operators, and the [a,b,c] literal syntax.


Slicing, indexing, etc, the other basic operations do not.

If you do: ubyte[] a = (cast(ubyte*) malloc(4)[0..4];, it will 
compile... and create a slice from the malloced memory. That's 
one way to create an array without GCing it.



In that case, am I not essentially just re-creating Array?


Array does a lot of other stuff too... you only really need 
append and maybe shrink for a static variable, since tracking 
ownership doesn't matter (it is never disappearing since it is 
global)


Oh really?!?! I thought slicing used the GC? Is this a recent 
development or always been that way?


ok, so if I just use a shared [], and create it using malloc(as 
you've done above) then release and remalloc when I need to 
append(not efficient but ok in my senario), then it won't use the 
GC?


If so, then I can handle that! I guess [] doesn't have a capacity 
field so I'll have to keep track of that. Other wise, it should 
be pretty simple.


Of course, I still feel like I'm trying to implement array 
because everything turns in to "lots of stuff" at some point ;/





Multidimension AA's and remove

2015-09-11 Thread Prudence via Digitalmars-d-learn
Error: template std.algorithm.mutation.remove cannot deduce 
function from argument types !()(bool delegate(void*, uint, uint, 
int)[], void), candidates are:
std.algorithm.mutation.remove(SwapStrategy s = 
SwapStrategy.stable, Range, Offset...)(Range range, Offset 
offset) if (s != SwapStrategy.stable && 
isBidirectionalRange!Range && hasLvalueElements!Range && 
hasLength!Range && Offset.length >= 1)
std.algorithm.mutation.remove(SwapStrategy s = 
SwapStrategy.stable, Range, Offset...)(Range range, Offset 
offset) if (s == SwapStrategy.stable && 
isBidirectionalRange!Range && hasLvalueElements!Range && 
Offset.length >= 1)
std.algorithm.mutation.remove(alias pred, SwapStrategy s = 
SwapStrategy.stable, Range)(Range range) if 
(isBidirectionalRange!Range && hasLvalueElements!Range)



coming from

static TValue[][TKey] s;

(s[key]).remove(c => value == c);

How to disambiguate or do what I'm trying to do:

I'm trying to create an associative array with multiple values 
per key. Hence the AA with an extra dynamic array on it.


I've tried

TValue[TKey][] s;

and other stuff without success(essentially same error about not 
being able to deduce remove)


I would expect (s[key]) to return the normal array.

I've tried this too.
remove!(c => this.Value == c)(store[this.Key], 
SwapStrategy.unstable);




At the very least: Is T[][S] an associative array with keys of 
type S and values of an array of type T or is it backwards? Also, 
how to disabmiguate


Thanks.



Re: shared array?

2015-09-11 Thread Prudence via Digitalmars-d-learn

On Friday, 11 September 2015 at 13:12:14 UTC, Adam D. Ruppe wrote:

On Friday, 11 September 2015 at 04:28:52 UTC, Prudence wrote:
I thought about that but then I have to rely on the GC for 
some simple things. Doesn't seem like the right way to go.


Since it is static, it will never be collected anyway, so you 
could just use it and it'll work for convenience and probably 
lose nothing, or very trivially write an append function that 
uses any scheme you want instead of doing ~= on it without even 
worrying about freeing it.


And that makes it worse!! If it's never collected and the GC 
scans it every time, it means it adds a constant overhead to the 
GC for absolutely no reason, right? It also then makes every 
dependency on it GC dependent(@nogc can't be used)? It just seems 
like it's the wrong way to go about it.







Re: shared array?

2015-09-11 Thread Prudence via Digitalmars-d-learn

On Friday, 11 September 2015 at 07:41:10 UTC, Kagamin wrote:

I get only one error:
Error: non-shared method std.container.array.Array!(void 
delegate()).Array.~this is not callable using a shared object.


It will try to destruct the array on program termination, but 
it requires the destructor to be aware of the shared context.


But in this case it is static, so why does it matter? Do you have 
any ideas how to wrap it or fix this?


Version for windows/console compilation?

2015-09-10 Thread Prudence via Digitalmars-d-learn
Is there a flag for knowing when a project is compiling for 
windows(Uses WinMain) vs a console(normal main)?


version(Windows) is always valid for a console app, so it is 
useless to disambiguate between a console app and a windows app. 
(Say I have both a main and a winmain in my code, I need to 
select between them(it's a bit more complex than this but)).





shared array?

2015-09-10 Thread Prudence via Digitalmars-d-learn

I can't create a shared array:

static Array!(bool delegate(int, WPARAM, LPARAM)) callbacks;

(prepending shared produce a ton of errors with the Array class)

I've tried making it a pointer and other things.


The array must be static and must be shared. Without shared 
everything works but I don't get, obviously, a useful array(it's 
empty because all the updating goes on in the main thread).


1. How do I create a shared array?
2. Why prepending shared produces any problems? I thought shared 
simply made a variable global to all threads?


Re: Version for windows/console compilation?

2015-09-10 Thread Prudence via Digitalmars-d-learn

On Friday, 11 September 2015 at 01:36:31 UTC, Mike Parker wrote:
On Thursday, 10 September 2015 at 18:10:43 UTC, Adam D. Ruppe 
wrote:


BTW it is pretty rare that you should actually write a WinMain 
in D. The right thing to do in most cases is to write a normal 
main function. You can still get the windows gui subsystem 
with a linker flag.


Specifically, add the following when using the Microsoft linker 
(compiling with -m64 or -m32mscoff):


-L/SUBSYSTEM:windows,6.00 -L/ENTRY:mainCRTStartup

And this when using OPTLINK:

-L/SUBSYSTEM:windows,5.01

The version numbers are optional. I use 6.00 with the MS linker 
because it covers both 32-bit and 64-bit apps on Vista and 
later, and is the default for the VS 2015 linker.


[1] https://msdn.microsoft.com/en-us/library/fcc1zstk.aspx

I don't think I've written a WinMain in D in 10 years.


I'm using Visual D and I assume it takes care of all this. It 
works so that's not a huge problem.


I'm simply creating my own version flags in VD properties. Not 
the best way because I'll have to remember to set the flags every 
time I use the library or I'll get errors about stuff missing. I 
was hoping D had a flag to disambiguate console and windows 
apps(or some type to CT way to check).





Re: shared array?

2015-09-10 Thread Prudence via Digitalmars-d-learn

On Friday, 11 September 2015 at 00:50:15 UTC, Adam D. Ruppe wrote:

On Friday, 11 September 2015 at 00:48:28 UTC, Prudence wrote:

static Array!(bool delegate(int, WPARAM, LPARAM)) callbacks;


Try just using a regular array instead of the library Array.


static bool delegate(int, WPARAM, LPARAM)[] callbacks;

my guess is the Array library thing isn't marked as shared 
internally.


I thought about that but then I have to rely on the GC for some 
simple things. Doesn't seem like the right way to go.




Concurency wtf?

2015-09-08 Thread Prudence via Digitalmars-d-learn


I can't seem to receive certain messages, my code is very simple 
and it all works except for receiving:



in one thread I do


locate("MyMonitor").send(cast(shared)pt);

which sends the message(pt is a windows POINT structure).

In the MyMonitor spawned thread, I have


while (true)
{
POINT y;
receiveTimeout(100.msecs,
(POINT p)
{
y = p;
}
);


Thread.sleep(100.msecs);
continue;
}


Note that everything works except the matching in receiveTimeout. 
(I've tired various things and simplifications to no avail).


I can send simple types like int and bool. e.g., sending a 
literal works fine. My guess is the shared is causing problems 
but I've tried all common sense combinations. But I have to send 
shared, else send complains about sending unshared types.


Of course, the great thing is, all examples use literals and 
hence not real world examples(isn't that nice?).


Please don't ask me to provide source. The issue has nothing to 
do with the other code but specifically the TYPE that is being 
sent. Works for some types and not others. It is almost surely 
due to the shared issue, any ideas?





Win32 function vs delegate issues with api

2015-09-08 Thread Prudence via Digitalmars-d-learn

I have

hook = SetWindowsHookEx(WH_MOUSE, , NULL, ThreadID);   

Proc is the standard hook proc:

public extern (Windows) LRESULT Proc(int code, WPARAM wParam, 
LPARAM lParam)


I get a type mismatch because Proc is a delegate and 
SetWindowsHookEx expects a function. Making proc static works but 
not the behavior I want since all this stuff is wrapped in a 
class.


Is there any way to pass Proc to SetWindowsHookEx without issues 
of GB and such?




Error: function windows.winuser.SetWindowsHookExA (int, extern 
(Windows) int function(int, uint, int), void*, uint) is not 
callable using argument types (const(int), extern (Windows) int 
delegate(int code, uint wParam, int lParam), void*, uint)		


I could cast Proc to a function, obviously, but I'll loose the 
delegate behavior and create problems when I try to use this 
inside Proc?





Re: Windows Header consts

2015-09-07 Thread Prudence via Digitalmars-d-learn
On that note, is there also any generic translation software for 
code that you can program a set of simple "rules"(matching and 
arranging) to translate source code?


e.g., match("const WM_", ";")->WM.add(%1 + ",")).

The above should be obvious but essentially it matches the first 
string until the second is found, adds it to the WM 
container(which, we can specify it it's type). %1 is just what 
was found inbetween the two bookends in the match. We add a comma 
for the next enum.


(such a line would put all the const WM's into the enum, it 
doesn't handle the outer static versioning, so would break 
headers... hence a more robust solution is needed)





Windows Header consts

2015-09-07 Thread Prudence via Digitalmars-d-learn
Windows headers contain a ton of global const's for the various 
messages. Seems like a very bad way to go about this.


Could one not simply put all these in an enum? e.g., enum WM { 
WM_CREATE = 1, etc... }?


If so, because there are so many and so many references to them, 
this can't be done easily by hand. Surely there is a way to 
automate this? But because the headers are not consistently 
written, a simple search and replace won't work well?


e.g.,

const WM_* -> add to enum WM;
else WM_* -> WM.*

because there is code like

static if (_WIN32_WINNT >= 0x500) {

enum {
WM_CHANGEUISTATE=   0x0127,
WM_UPDATEUISTATE=   0x0128,
WM_QUERYUISTATE =   0x0129
}

// LOWORD(wParam) values in WM_*UISTATE*
enum {
UIS_SET =   1,
UIS_CLEAR   =   2,
UIS_INITIALIZE  =   3
}

// HIWORD(wParam) values in WM_*UISTATE*
enum {
UISF_HIDEFOCUS  =   0x1,
UISF_HIDEACCEL  =   0x2
}

}

static if (_WIN32_WINNT >= 0x501) {

// HIWORD(wParam) values in WM_*UISTATE*
enum {
UISF_ACTIVE =   0x4
}

}

(unless one can define partial enums or use static if in the 
enums directly(probably the case but parsing is more difficult))



I guessing one would need a D or C parser to deal with all this?



Re: Windows Header consts

2015-09-07 Thread Prudence via Digitalmars-d-learn

On Monday, 7 September 2015 at 20:55:25 UTC, Adam D. Ruppe wrote:

On Monday, 7 September 2015 at 19:06:48 UTC, Prudence wrote:
It's called encapsulation. It prevents namespace pollution and 
identifier collision.


This is already provided by the D module system. Even if you 
were to define a WM_CREATE in your code, it would not cause a 
major problem with the Win32 name because you can disambiguate 
via the imports. (That's also a minor hassle, but it is more 
rare for these long names than a short name like WM anyway!)


My editor already autocompletes WM_* names anyway, but again, 
the D module system can help with that too if you didn't want 
the keyword based completion I use for that.


I just don't see any advantage here to counterbalance the pain 
of changing it.


Again, it's called progress. Why keep using the same defunct 
system for endless years simply because that's the way it was 
done?


It's like saying we should never upgrade the space shuttle(not 
that it matters any more) simply because the previous one was 
working?


Do you seriously think that your logic is the best? If you could 
prove that Bill Gates designed the best OS ever possible, that is 
one thing... But changes are they shit all over themselves while 
doing it because they didn't learn from there mistakes(how could 
they, they go in to the future to see what kinda crap came out).


Do you think computers in 100 years are still going to be using 
windows? Do you think the designers will still use the same 
programming techniques? Do you think they will worship Bill Gates 
because think they the messaging model of Windows was the 
ultimate gift to humanity?


It's one thing to say: "I'm just too lazy to want to waste all 
that time changing stuff to make it work". That's a valid 
argument! But it's quite different to say "We don't need to 
change because this model works best and any modification of it 
will only produce a poorer result". If you are going to use the 
second argument, you need to prove it. If you are going to use 
the first, don't expect to get anywhere.


I just wish when people say stuff like you have done, you would 
be honest and say what you really mean so we don't have to waste 
time beating around the bush. A simple "I'm don't care what 
others want, I think we should keep it the same because I'm happy 
with it". I'm OK with such a statement. At least it's honest and 
direct. I might not like the selfishness that it implies, but to 
each his own, I suppose.


Oh, and who says you couldn't keep both systems? But I'll never 
understand why people think keeping a junker around and NOT allow 
something better is a good idea. You can keep your rusted ol' 
ElCamino that's missing a tire and has no hood if you want. But 
why stop me from having a Ferrari? Is it jealousy? Selfishness? 
There's enough gas to go around you know? And if we both arrive 
at the gas station we can take turns, if your willing?








Re: Windows Header consts

2015-09-07 Thread Prudence via Digitalmars-d-learn

On Monday, 7 September 2015 at 22:21:28 UTC, Adam D. Ruppe wrote:

On Monday, 7 September 2015 at 22:02:47 UTC, Prudence wrote:

Oh, and who says you couldn't keep both systems?


Nobody. There's absolutely nothing stopping you from defining 
your one constants and bindings. I think you should actually do 
it and see for yourself the pros and cons in practice.


Which is why I asked is there is an easy way to do it, and you 
replied that essentially that it shouldn't be changed because it 
would change things.


Re: Windows Header consts

2015-09-07 Thread Prudence via Digitalmars-d-learn

On Monday, 7 September 2015 at 17:59:43 UTC, Adam D. Ruppe wrote:

On Monday, 7 September 2015 at 17:44:54 UTC, Prudence wrote:

const WM_* -> add to enum WM;
else WM_* -> WM.*


I'm against that. The documentation all says WM_* and we 
shouldn't muck with it.




huh?
Are you saying you don't like to use

WM.Create

because it is confusing and hard for you to understand over

WM_Create?

Did you do a lot of win32 programming back in the day?




Re: Windows Header consts

2015-09-07 Thread Prudence via Digitalmars-d-learn

On Monday, 7 September 2015 at 18:58:08 UTC, Adam D. Ruppe wrote:

On Monday, 7 September 2015 at 18:42:59 UTC, Prudence wrote:

because it is confusing and hard for you to understand over


Nope, I'm saying it is a pointless change. If you do that, 
EVERY time you want to look something up, you need to rewrite 
WM.* into WM_* since that's what the docs say. And then EVERY 
time you copy/paste code from C or, again, the docs, you need 
to change it the other way. (and moreover, it won't even work, 
since like you pointed out, some enums have static if in part)



That's a big hassle... and what's the benefit? What do you 
actually gain by doing this?




It's called encapsulation. It prevents namespace pollution and 
identifier collision. It also makes intelligent easier, not to 
mention looks nicer, keeps everything tidy, and everything else 
that makes coding easier.


If you think mentally changing a . to a _ is a hassle then your 
in trouble! An apple a day simply won't help!


I understand porting code won't be as easy but a simple WM_ to WM 
replacement would fix 99% of the problems. Oh well, some people 
just don't like progress! Do you want to go back to using wooden 
wheels too? Is that better because it's easier to understand than 
the complexity of vulcanized rubber and carbon steel?




Did you do a lot of win32 programming back in the day?


Yup, and I still do. The documented names have worked for 
twenty years, why change them now?


That's what I figured! Get out of the dark ages!




Re: Interface "indexing"

2015-09-06 Thread Prudence via Digitalmars-d-learn

On Sunday, 6 September 2015 at 18:11:44 UTC, Kagamin wrote:

Well, you can have an array of event factories:

IEvent function()[2] factories = [ factory1, factory2 ];

IEvent factory1() { return new Event1(); }
IEvent factory2() { return new Event2(); }

Then use enum for indexing:
IEvent e = factories[NumEvent1]();


Yes, I suppose an array would work, but realize that since enum 
is a compile time construct, the dynamic array is not necessary. 
And since your factories are all the time and always will be(if 
you change anything you have to refactor a lot of stuff).


It seems all this stuff could be simplified a great deal. And no 
one said you wouldn't have a switch. I'm not talking about 
creating some tycheyon particles. I'm simply talking about some 
way to hide the details(which, could be done with a string mixin 
but at the cost of not being able to parse them and debug them 
well).





Re: Windows Resources

2015-09-06 Thread Prudence via Digitalmars-d-learn

On Sunday, 6 September 2015 at 10:28:59 UTC, Kagamin wrote:

On Sunday, 6 September 2015 at 02:37:21 UTC, Prudence wrote:
Obviously the issue is that I'm not using any resources yet it 
is giving me such an error.


You do. See docs for lpszMenuName field. GUI projects generated 
by Visual Studio include resource generation, that's why it 
works for them.


Thanks!

So how does one actually include resources such as menu's (rc 
files and all that) in a D project? Or am I stuff creating all 
that stuff programmatically?





Create a delegate function

2015-09-05 Thread Prudence via Digitalmars-d-learn
I have code setup in such a way that I call a user defined 
function, e.g.,


void myFunc(Data d)
{

}

myFunc has to be passed to the main code using something like

void SetFunc(void function(Data) func) { ... func(myData); }

What I would like to do is, instead of having to pass data to 
myFunc(and use the type Data in all the function types), is to 
sort of create a delegate:


what I want to do:

void myFunc()
{
  this.d;  // Ok, because somehow this = Data;
}

then, of course,

void SetFunc(void delegate() func) { func.context = myData; 
func(); }





void delegate() dg =
{
auto t = this;
return;
};

doesn't even work because this is not defined.


My guess this is impossible without compiler support.

effectively though, I don't see why we can't use this(because 
myFunc is being executed in a context, I simply want to set it to 
the right one so that the user can take advantage of it... 
instead of having to pass an argument instead.



Any ideas how to do this? It seems we can't actually create 
"delegate objects" but only delegate pointers? (simply because of 
the restrictions the compiler places on *this*. (can't be used 
outside of a context, even though we can always guarantee it is 
in a context)


How bout a new syntax for such concepts?

void delegate!T(...) dg
{

}

// identical to

void dg(T this, ...)
{

}


Hence, to call dg, we have to pass it a "this" object... hence it 
has a context. They can be called just like functions. dg(myData, 
...);





Windows Resources

2015-09-05 Thread Prudence via Digitalmars-d-learn
I'm trying to create a win32 window. I coped the code pretty much 
directly from msdn:


MSG msg;
BOOL bRet;
WNDCLASS wc;

// Register the window class for the main window.

if (!hPrevInstance)
{
wc.style = 0;
wc.lpfnWndProc = cast(WNDPROC)
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
//wc.hIcon = LoadIcon(cast(HINSTANCE) NULL, 
IDI_APPLICATION);
//wc.hCursor = LoadCursor(cast(HINSTANCE) NULL, 
IDC_ARROW);
wc.hIcon = NULL;
wc.hCursor = NULL;
wc.hbrBackground = GetStockObject(WHITE_BRUSH);
wc.lpszMenuName =  "MainMenu";
wc.lpszClassName = "MainWndClass";

if (!RegisterClass())
return FALSE;
}

// Create the main window.
hwndMain = CreateWindow("MainWndClass", "Sample",

WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, 
CW_USEDEFAULT, cast(HWND) NULL,
cast(HMENU) 
NULL, hInstance, cast(LPVOID) NULL);
if (!hwndMain)
{
auto x = GetLastError();
return FALSE;
}


x is 1812 = ERROR_RESOURCE_DATA_NOT_FOUND

That's about as far as I can get. (what resource data? Where I do 
put it? How, who, when?)





Re: Windows Resources

2015-09-05 Thread Prudence via Digitalmars-d-learn

On Sunday, 6 September 2015 at 00:29:13 UTC, Adam D. Ruppe wrote:

On Saturday, 5 September 2015 at 19:06:15 UTC, Prudence wrote:
That's about as far as I can get. (what resource data? Where I 
do put it? How, who, when?)


Resource data in Windows is data compiled into your exe. It is 
stuff like icons, menus, or other arbitrary stuff you attach.


However, the code you posted doesn't access any of that so it 
shouldn't be an issue here... what import did you use to access 
the windows api? `import core.sys.windows.windows;` or 
something else? Also, are you building 32 bit (the default) or 
64 bit?


32-bit and I'm using the latest win32 wrappers distributed on 
github from someone. (suppose to be more complete than 
core.sys.windows)


Obviously the issue is that I'm not using any resources yet it is 
giving me such an error. (again, I pretty much copied the code 
directly from MSDN)






Abstractioning away main/winMain

2015-09-04 Thread Prudence via Digitalmars-d-learn

Standard and Win32 apps are so old school!

I'd like to hide WinMain by wrapping it in an application 
class(more or less).


Essentially I have an Application class

class Application
{
   public static Application New(void delegate() entry)
   {

   }
}


 Another module

extern (Windows) int WinMain(...)
{


}

 User Module:


const MyApp = Application.New({ std.stdio.writeln("MY APP IS 
COOL"); });



But the lamba runs into a problem because of the static nature of 
the program... much less figuring out how to hook WinMain up into 
it.


Essentially I don't want the user ever to have to know how there 
entry point came into being but there is this funkyness about it 
because Application never gets any control to call the user's 
Entry function. Whats worse is that D tries to evaluate the 
lambda at compile time. It's as if D only allows non-static data 
inside functions.



The idea is to have WinMain actually call the Entry lamba 
function once it gets ran(transfer control)... but this seems to 
be difficult or impossible with D and I'm not sure why or, if 
not, how to get it to work without having to make the user jump 
through hoops.


I suppose I could create the Application(Using New instead of 
new) inside of WinMain, but the issue still remains on how to get 
the user entry point(I suppose some compile time reflection could 
be used?).


Any ideas?

(The main reason for doing this is to make it easier for writing 
portable apps)







Re: Abstractioning away main/winMain

2015-09-04 Thread Prudence via Digitalmars-d-learn
On Saturday, 5 September 2015 at 01:49:22 UTC, Adam D. Ruppe 
wrote:

On Saturday, 5 September 2015 at 01:43:43 UTC, Prudence wrote:

extern (Windows) int WinMain(...)


If you use WinMain in D, you'll also have to initialize the D 
runtime yourself, which will call static constructors and such.


You'd be better off just using a regular main() function, then 
passing the `-L/SUBSYSTEM:WINDOWS:5.0` option to dmd when 
building (at least on 32 bit, not sure if it is the same on 64 
bit or not) so the linker makes a gui app - same as it does 
when it detects a WinMain in the program.



const MyApp = Application.New({ std.stdio.writeln("MY APP IS 
COOL"); });


Remember, gui apps don't necessarily have a console, so writeln 
may fail!


Maybe, but the error relates to be being called statically.



(The main reason for doing this is to make it easier for 
writing portable apps)



Just using a regular main function is the most portable 
solution. Then just offer helper functions or something to help 
with the boilerplate.


Essentially that is what I'm doing. I have divided the app into 
different types using versioning. The application class is a 
generic wrapper for the main possibilities(win32, Win64, mac, 
linux, etc).


Basically WinMain is used when version is Win32 or Win64 so it is 
not a problem with the stuff you have mentioned. At some point I 
will make it all work but I need to get off the ground first. I 
can always force the user to jump through some hoops but I'd like 
to avoid that as much as possible since I'm the user and I don't 
like hoops.







Re: Abstractioning away main/winMain

2015-09-04 Thread Prudence via Digitalmars-d-learn

If I use functions instead of delegates it works.

I suppose the problem then is that the delegate can't create a 
fat pointer when used in a static context. (i.e., why the 
functions work)


The question is, then, Can I construct a delegate manually and 
supply my own context pointer?


e.g.,
class X { }

void foo() { }

constructDelegate(, new X()) // Creates a void delegate() 
with context X