Re: Delegates: Print 0..9

2016-12-01 Thread unDEFER via Digitalmars-d-learn

On Thursday, 1 December 2016 at 20:12:15 UTC, Ali Çehreli wrote:


First, the scary syntax that produces a lambda from an int:
...
Better:
...


All methods.. Thank you!


Re: Two part question. Making a dynamic array of delegates, and taking in a delegate with unknown parameters as an argument .

2016-12-01 Thread Payotz via Digitalmars-d-learn
Thank you all for the replies. I'm extremely grateful. I'll look 
into each and every answer.


Re: Two part question. Making a dynamic array of delegates, and taking in a delegate with unknown parameters as an argument .

2016-12-01 Thread Mike Parker via Digitalmars-d-learn

On Thursday, 1 December 2016 at 23:51:19 UTC, Payotz wrote:

The register method will take in delegates as an argument, but 
those delegates have varied arguments themselves, so I can't 
really put anything there. I know that it's got something to do 
with templates so I tried my hand in it and came up with this:


void registerEvent(string event_name,T...)(T delegate() dg);


Off the top of my head, you should be able to do something like 
this:


void registerEvent(string event_name, T, Args...)(T 
delegate(Args) dg) {}





I know there's something missing in the way I did it, so I'll 
be glad for you folks to tell me what I'm missing.


And for the second part of the question, I can't seem to make a 
Dynamic Array where I could store the delegates taken in the 
"registerEvent" method. Closest thing I have gotten to is this:


private void delegate(T)(T args)[string] event;

which resulted in the compiler screaming Error signs at me.
So how does one do it?


This isn't going to work because you can't have an array of mixed 
types. Something like `KyeEvent delegate() dg` and `MouseEvent 
delegate() dg` are distinct types, so they can't be stored in the 
same array.


Since you say the delegates have different parameters, the only 
option I'm aware of to store them is to use either the Variant or 
Algebraic type in std.variant. If only the return type differed, 
there would be other options. And I don't know what you're doing 
with that event_name template parameter. But anyway, checkout 
std.variant.


Re: Two part question. Making a dynamic array of delegates, and taking in a delegate with unknown parameters as an argument .

2016-12-01 Thread Nicholas Wilson via Digitalmars-d-learn

On Thursday, 1 December 2016 at 23:51:19 UTC, Payotz wrote:
So, to give context, I am trying to make an event manager for a 
game I'm making.

I was writing the "register()" method so I ran into a problem.

The register method will take in delegates as an argument, but 
those delegates have varied arguments themselves, so I can't 
really put anything there. I know that it's got something to do 
with templates so I tried my hand in it and came up with this:


void registerEvent(string event_name,T...)(T delegate() dg);



You could do what pthread does in C to achieve similar goals.

void delegate(void*); // or int delegate(void*) if you want 
to return an error code

and then store the void pointer along with the delegate
and then cast the void* to the correct type (a struct of 
arguments or similar) and call it later. not very safe but there 
are ways to make it nicer.


However if the set of types of events is closed you can use

ailas event = Algebraic!(ev1,ev2,ev3...);

where ev1 and so on are structs that hold parameters of the event.
and have

void delegate(event);

This is effectively how SDL does events.

I know there's something missing in the way I did it, so I'll 
be glad for you folks to tell me what I'm missing.


And for the second part of the question, I can't seem to make a 
Dynamic Array where I could store the delegates taken in the 
"registerEvent" method. Closest thing I have gotten to is this:


private void delegate(T)(T args)[string] event;

which resulted in the compiler screaming Error signs at me.
So how does one do it?


You get an error here because you are trying to have an 
associative array of templates. if they were all void 
delegate(int)'s that would work. You can't use an uninstantiated 
template as a type.




Re: Two part question. Making a dynamic array of delegates, and taking in a delegate with unknown parameters as an argument .

2016-12-01 Thread crimaniak via Digitalmars-d-learn

On Thursday, 1 December 2016 at 23:51:19 UTC, Payotz wrote:
So, to give context, I am trying to make an event manager for a 
game I'm making.

I was writing the "register()" method so I ran into a problem.

The register method will take in delegates as an argument, but 
those delegates have varied arguments themselves, so I can't 
really put anything there. I know that it's got something to do 
with templates so I tried my hand in it and came up with this:


void registerEvent(string event_name,T...)(T delegate() dg);


May be std.variant will help you. 
https://dlang.org/phobos/std_variant.html
You can bring the delegates to a common interface, hiding the 
differences in std.variant


Re: Two part question. Making a dynamic array of delegates, and taking in a delegate with unknown parameters as an argument .

2016-12-01 Thread Ali Çehreli via Digitalmars-d-learn

On 12/01/2016 03:51 PM, Payotz wrote:
> So, to give context, I am trying to make an event manager for a game I'm
> making.
> I was writing the "register()" method so I ran into a problem.
>
> The register method will take in delegates as an argument, but those
> delegates have varied arguments themselves, so I can't really put
> anything there.

What you know is how you will call them. Let's assume just an int argument.

> I know that it's got something to do with templates so I
> tried my hand in it and came up with this:
>
> void registerEvent(string event_name,T...)(T delegate() dg);

Binding state to callables is pretty easy in D. You don't want to pass 
the arguments to the registration because it wouldn't know what to do 
with those: Store the state for the delegate? Maybe, maybe not.


> I know there's something missing in the way I did it, so I'll be glad
> for you folks to tell me what I'm missing.

All you need is your interface to these callbacks.

> And for the second part of the question, I can't seem to make a Dynamic
> Array where I could store the delegates taken in the "registerEvent"
> method. Closest thing I have gotten to is this:
>
> private void delegate(T)(T args)[string] event;
>
> which resulted in the compiler screaming Error signs at me.
> So how does one do it?

Here is a start:

import std.stdio;

alias Func = void delegate(int);

Func[string] registry;

void register(string event_name, Func func) {
registry[event_name] = func;
}

struct S {
double d;
string s;

void foo(int i) {
writefln("S.foo called with %s; my state: %s", i, this);
}
}

void bar(int i) {
writefln("bar called with %s", i);
}

void main() {
register("trivial", (int a) => writefln("called with %s", a));

auto s = S(2.5, "hello");
register("with_struct", );

int j;
register("using_local_state", (int a) {
++j;
writefln("Incremented local j: %s", j);
});

// This won't work as  because  is not a delegate, but a 
function.

// Very simple with toDelegate.
// http://dlang.org/phobos/std_functional.html#toDelegate
import std.functional: toDelegate;
register("regular_function", toDelegate());

foreach (event_name, func; registry) {
writefln("--- Calling function registered for %s", event_name);
func(cast(int)event_name.length);
}
}

Ali



Re: Two part question. Making a dynamic array of delegates, and taking in a delegate with unknown parameters as an argument .

2016-12-01 Thread H. S. Teoh via Digitalmars-d-learn
On Thu, Dec 01, 2016 at 11:51:19PM +, Payotz via Digitalmars-d-learn wrote:
> So, to give context, I am trying to make an event manager for a game
> I'm making.
> I was writing the "register()" method so I ran into a problem.
> 
> The register method will take in delegates as an argument, but those
> delegates have varied arguments themselves, so I can't really put
> anything there. I know that it's got something to do with templates so
> I tried my hand in it and came up with this:
> 
> void registerEvent(string event_name,T...)(T delegate() dg);
> 
> I know there's something missing in the way I did it, so I'll be glad
> for you folks to tell me what I'm missing.
> 
> And for the second part of the question, I can't seem to make a
> Dynamic Array where I could store the delegates taken in the
> "registerEvent" method.  Closest thing I have gotten to is this:
> 
> private void delegate(T)(T args)[string] event;
> 
> which resulted in the compiler screaming Error signs at me.
> So how does one do it?

This requires heavy trickery, because what you're essentially doing is
taking a compile-time construct (type-safe variadic functions) and
applying it at runtime (array elements don't know how many arguments
they will have until actually initialized at runtime). The solution is
non-obvious, but, thankfully, *possible*, 'cos D is just *that* awesome.
;-)

An example of how to do this can be found in Adam Ruppe's eventloop.d
module, available here:

https://github.com/adamdruppe/arsd/blob/master/eventloop.d

In particular, look at the `typehash` template, the addListener() and
send() functions, and the WrappedListener interface (along with the
wrap() function). That should give you the basic idea of what's
involved. Past that, there are also some dirty implementation details
you have to work with such as getPtrPair() that performs some
compiler-dependent type-casting black magic just to tie things together.

(Alternatively, you could just use eventloop.d in your game and save
yourself the trouble of reinventing it yourself. ;-)  It has a pretty
nice API that I've used in my own projects quite successfuly.)


T

-- 
Shin: (n.) A device for finding furniture in the dark.


Two part question. Making a dynamic array of delegates, and taking in a delegate with unknown parameters as an argument .

2016-12-01 Thread Payotz via Digitalmars-d-learn
So, to give context, I am trying to make an event manager for a 
game I'm making.

I was writing the "register()" method so I ran into a problem.

The register method will take in delegates as an argument, but 
those delegates have varied arguments themselves, so I can't 
really put anything there. I know that it's got something to do 
with templates so I tried my hand in it and came up with this:


void registerEvent(string event_name,T...)(T delegate() dg);

I know there's something missing in the way I did it, so I'll be 
glad for you folks to tell me what I'm missing.


And for the second part of the question, I can't seem to make a 
Dynamic Array where I could store the delegates taken in the 
"registerEvent" method. Closest thing I have gotten to is this:


private void delegate(T)(T args)[string] event;

which resulted in the compiler screaming Error signs at me.
So how does one do it?


Re: The module 'foo' is already defined in 'libmylib.so'

2016-12-01 Thread Nicholas Wilson via Digitalmars-d-learn

On Thursday, 1 December 2016 at 22:05:06 UTC, Timothee Cour wrote:
I want to update a library with new symbols (ie partial 
recompilation):


libmylib.so : compiled from bar.d and foo.d

now update the file foo.d

dmd -c -fPIC foo.d -offoo.o

clang++ -o libmylib_update.so foo.o -shared -Wl,-lmylib

When trying to dlopen libmylib_update.so from C++ it fails 
with: The module 'foo' is already defined in 'libmylib.so'


(it somehow works when the dlopen is called from D)

How would I achieve that?


Have a look at what `trace -E d_executable args` and `trace -E 
c++_executable args`

print on startup and grep for dlopen calls and the like.


The module 'foo' is already defined in 'libmylib.so'

2016-12-01 Thread Timothee Cour via Digitalmars-d-learn
I want to update a library with new symbols (ie partial recompilation):

libmylib.so : compiled from bar.d and foo.d

now update the file foo.d

dmd -c -fPIC foo.d -offoo.o

clang++ -o libmylib_update.so foo.o -shared -Wl,-lmylib

When trying to dlopen libmylib_update.so from C++ it fails with:
The module 'foo' is already defined in 'libmylib.so'

(it somehow works when the dlopen is called from D)

How would I achieve that?


Re: Delegates: Print 0..9

2016-12-01 Thread Ali Çehreli via Digitalmars-d-learn

On 12/01/2016 11:28 AM, unDEFER wrote:
> Hello!
> Simple using of delegates:
>
> ===
> #!/usr/bin/rdmd
> import std.stdio;
>
> void main()
> {
> void delegate() functions[];
>
> foreach (i; 0..10)
> {
> void print()
> {
> writefln("%s", i);
> }
>
> functions ~= 
> }
>
> foreach (i; 0..10)
> {
> functions[i]();
> }
> }
> =
>
> Prints
> $ ./delegates.d
> 9
> 9
> 9
> 9
> 9
> 9
> 9
> 9
> 9
> 9
>
> How to print 0..9?

This is a common issue with D and some other languages (as I had learned 
during a Dart language presentation, of which Dart does not suffer 
from). All those delegates do close on the same loop variable. You need 
to produce copies of the variable.


First, the scary syntax that produces a lambda from an int:

import std.stdio;

void main()
{
// Note: dmd's -de command line switch warned me about the use of
// C-style syntax, so I moved the brackets after the type name:
void delegate()[] functions;

foreach (i; 0..10)
{
void print(int j)
{
writefln("%s", j);
}

functions ~= ((a) => (() => print(a)))(i); // <-- SCARY
}

foreach (i; 0..10)
{
functions[i]();
}
}

Better:

// Returns a lambda
auto makePrinter(int j) {
return {  // <-- returns a lambda
writefln("%s", j);
};
}

functions ~= makePrinter(i);

But of course there are better ways of doing things e.g. producing 
numbers. Here is one with D's ranges:


import std.stdio: writeln;
import std.range: iota;
import std.algorithm: each;

void main() {
10.iota.each!writeln;
}

Ali



Re: Delegates: Print 0..9

2016-12-01 Thread unDEFER via Digitalmars-d-learn

Yes, I have found:

=
#!/usr/bin/rdmd
import std.stdio;

void main()
{
void delegate() functions[];

foreach (i; 0..10)
{
auto get_print(int i)
{
void print()
{
writefln("%s", i);
}

return 
}

functions ~= get_print(i);
}

foreach (i; 0..10)
{
functions[i]();
}
}
=

Thank you!


Re: how to catch D Throwables (or exceptions) from C++?

2016-12-01 Thread Rémy Mouëza via Digitalmars-d-learn

On Thursday, 1 December 2016 at 01:58:13 UTC, Timothee Cour wrote:

eg:

```
dlib.d:
extern(C) void dfun(){assert(0, "some_msg");}

clib.cpp:
extern "C" void dfun();
void fun(){
  try{
dfun();
  }
  catch(...){
// works but how do i get "some_msg" thrown from D?
  }
}
```


I had the a similar problem when writing bindings to the RtMidi 
library back in 2013.
I opted for catching C++ exceptions in C++, wrap the functions in 
a C API; the C API returns a special type that contains a status, 
a result and an error message.
On the D side, when a status is false, a D exception is raised, 
mirroring the one that was caught in C++.

This strategy is described in dconf 2014:
https://www.youtube.com/watch?v=1JZNvKhA3mA=20m45s

It should be working the other way arround: catch a D exception 
in D, return a wrapped value: on the C++ side, if the wrapped 
value status is false, throw an exception


Below is an sample of the code I wrote:

In C++:
```
* Special return type.
 * - success is true when a call went right,
 *   is false when an exception occured.
 * - errMsg can be used to throw a D exception.
 * - value is the value to be returned from a call.
 */
template 
struct answer {
int success;
T value;
const char * errMsg;
};

* Predefined types of return for RtMidi. */
typedef answer answerRtMidiIn_p;
typedef answer answerRtMidiOut_p;
typedef answer answerBool;
typedef answer answerConstChar_p;
typedef answer answerDouble;

answerRtMidiIn_p RtMidiIn_new (
int api,
char * clientName,
unsigned int queueSizeLimit)
{
RtMidiIn * ptr;

try {
const std::string name = std::string (clientName);
ptr = new RtMidiIn ((RtMidi::Api) api, name, 
queueSizeLimit);

answerRtMidiIn_p ans = {true, ptr, ""};
return ans;

} catch (RtError & error) {
answerRtMidiIn_p ans = {false, 0, error.getMessage 
().c_str ()};

return ans;
}
}
```

in D:
```
/* Special return type.
 * - success is true when a call went right,
 *   is false when an exception occured.
 * - errMsg can be used to throw a D exception.
 * - value is the value to be returned from a call.
 */
struct answer (T) {
int success;
T value;
const (char) * errMsg;
}

extern (C) {
// ...
answer!(void *) RtMidiIn_new (
int api,
immutable(char) * clientName,
uint queueSizeLimit);
// ...
}

class RtMidiIn {
// Pointer to the C++ class, package visibility.
protected void * ptr;

public:

this (
int api = UNSPECIFIED,
string clientName = "RtMidi Input Client",
uint queueSizeLimit = 100)
{
answer!(void *) ans
= RtMidiIn_new (api,
clientName.toStringz,
queueSizeLimit);

if (! ans.success)
throw new RtError (ans.errMsg.to!string);

this.ptr = ans.value;
}

// ...
}
```




Delegates: Print 0..9

2016-12-01 Thread unDEFER via Digitalmars-d-learn

Hello!
Simple using of delegates:

===
#!/usr/bin/rdmd
import std.stdio;

void main()
{
void delegate() functions[];

foreach (i; 0..10)
{
void print()
{
writefln("%s", i);
}

functions ~= 
}

foreach (i; 0..10)
{
functions[i]();
}
}
=

Prints
$ ./delegates.d
9
9
9
9
9
9
9
9
9
9

How to print 0..9?


Re: How to serialize a double.

2016-12-01 Thread Jake Pittis via Digitalmars-d-learn

On Thursday, 1 December 2016 at 07:13:45 UTC, Bauss wrote:

On Thursday, 1 December 2016 at 00:36:30 UTC, Jake Pittis wrote:

[...]


You could do something like below which will allow you to 
serialize any number.



import std.stdio : writeln;
import std.traits : isNumeric;

ubyte[] bytes(T)(T num) if (isNumeric!T) {
auto buf = new ubyte[T.sizeof];

(*cast(T*)(buf.ptr)) = num;

return buf;
}

T value(T)(ubyte[] buf) if (isNumeric!T) {
return (*cast(T*)(buf.ptr));
}


And example usage:

double foo = 3.14;

writeln(foo); // Prints 3.14

ubyte[] bar = foo.bytes;

writeln(bar); // Prints the bytes equal to 3.14

foo = bar.value!double;

writeln(foo); // Prints 3.14



Regarding the test assertion that failed. Turns out I had a bug 
in the test. (of course)

This last solution is very pretty. Thanks.

You folks are all so kind!