Re: Delegates and classes for custom code.

2018-04-17 Thread Simen Kjærås via Digitalmars-d-learn

On Wednesday, 18 April 2018 at 01:12:33 UTC, Chris Katko wrote:

My only questions are:

[snip]

How's about this one:

import std.stdio : writefln;

struct data_to_access_t
{
int tacos;
}

class Abc(T, alias Fn) {
T data;

this(T data) {
this.data = data;
}

void execute() {
Fn(data);
}
}

Abc!(T, Fn) abc(alias Fn, T)(T data) {
return new Abc!(T, Fn)(data);
}

unittest {
data_to_access_t  d;
auto a = abc!((f) => writefln("test  %d", f.tacos))(d);
a.execute();
}

One problem with this approach is that two seemingly identical 
instantiations are different types. This may or may not be a 
problem in your specific case. If it is:


import std.stdio : writefln;
import std.functional : toDelegate;

struct data_to_access_t
{
int tacos;
}

class Abc(T) {
T data;
void delegate(T) Fn;

this(T data, void delegate(T) Fn) {
this.data = data;
this.Fn = Fn;
}

void execute() {
Fn(data);
}
}

Abc!(T) abc(alias Fn, T)(T data) {
static if (__traits(isTemplate, Fn))
return new Abc!(T)(data, Fn!T);
else
return new Abc!(T)(data, Fn.toDelegate);
}

unittest {
data_to_access_t  d;
auto a = abc!((f) => writefln("test  %d", f.tacos))(d);
auto b = abc!((data_to_access_t f) => writefln("test  %d", 
f.tacos))(d);

a.execute();
b.execute();
}

--
  Simen


Re: Delegates and classes for custom code.

2018-04-17 Thread arturg via Digitalmars-d-learn

On Wednesday, 18 April 2018 at 01:58:40 UTC, arturg wrote:


is it this what you want?

   class A
   {
   int a;
   void delegate() onDraw;

   this(void delegate() dg)
   {
   onDraw = dg;
   }

   void drawText(string s)
   {
   s.writeln;
   }
   }

   void main()
   {
A a;
a = new A((){ a.a = 5; a.drawText("test"); "drawing 
all".writeln; });

}

but if you do A a = new A((){ a.a = 5; ...});
the dg cant capture 'a' yet.
so maybe it would be better to just do:
A a = new A;
a.onDraw = (){ a.drawText("test"); "draw rest".writeln; };


ah i see bauss already wrote the same.

some other aproach could be:

class Base
{
final void draw()
{ drawSelf(); }

abstract void drawSelf();
}

class A : Base
{
override void drawSelf()
{ ... }
}


Re: Delegates and classes for custom code.

2018-04-17 Thread arturg via Digitalmars-d-learn

On Wednesday, 18 April 2018 at 01:12:33 UTC, Chris Katko wrote:

That was all pseudo-code typed by hand.

I got my code to work today. I don't know if it's the prettiest 
it can be, but it works:


// TESTING ACCESS TO the OWNING function
//---
class test_window
{
float x;
float y;

void draw_text(string text)
{
writeln(text);  
}

this( void function(test_window) onDraw  )
{   
this.onDraw = onDraw;
}

void run() //called every frame
{
onDraw(this);
}

void function (test_window) onDraw;
}


void test_dialog()
{
auto t = new test_window(function void(test_window ptr)
{
with(ptr)
{
draw_text( format("Hello, world. [x,y]=[%f,%f]", x, y));
}
});

t.run();
}





And a second attempt/version:





// TESTING ACCESS to anything
// --

struct data_to_access_t
{
int tacos;
}

struct data_to_access2_t
{
struct beans
{
int x;
};

beans b;
}

class abc(T)
{
int x;
void delegate(T) run_delegate;

T data;

this(T t, void delegate(T) d)
{
data = t;
run_delegate = d;
}

void execute()
{
run_delegate(data);
}
}

void test_dialog_anything()
{   
data_to_access_t  d;
data_to_access2_t d2;
d.tacos = 4;
d2.b.x  = 5;

	auto x = new abc!data_to_access_t ( d, (d) => writefln("test  
%d", d.tacos)  );
	auto y = new abc!data_to_access_t ( d, (d){writefln("test  
%d", d.tacos);}  );
	auto z = new abc!data_to_access2_t(d2, delegate void 
(d2){writefln("test2 %d", d2.b.x);}  );


x.execute();
y.execute();
z.execute();
}





My only questions are:

 -  is there any way to make it "smart" enough to take the type 
of the argument, instead of me manually giving it a type.


	auto x = new abc!data_to_access_t ( d, (d) => writefln("test  
%d", d.tacos)  );

becomes
auto x = new abc( d, (d) => writefln("test  %d", d.tacos)  );

 - Is there any way to eliminate the first d? Which is 
essentially a "this" pointer.


	auto x = new abc!data_to_access_t ( d, (d) => writefln("test  
%d", d.tacos)  );

becomes
	auto x = new abc!data_to_access_t ( (d) => writefln("test  
%d", d.tacos)  );


 - And preferably, if possible, both. But I'll take what I can 
get.


is it this what you want?

   class A
   {
   int a;
   void delegate() onDraw;

   this(void delegate() dg)
   {
   onDraw = dg;
   }

   void drawText(string s)
   {
   s.writeln;
   }
   }

   void main()
   {
A a;
a = new A((){ a.a = 5; a.drawText("test"); "drawing 
all".writeln; });

}

but if you do A a = new A((){ a.a = 5; ...});
the dg cant capture 'a' yet.
so maybe it would be better to just do:
A a = new A;
a.onDraw = (){ a.drawText("test"); "draw rest".writeln; };


Re: Delegates and classes for custom code.

2018-04-17 Thread Chris Katko via Digitalmars-d-learn

That was all pseudo-code typed by hand.

I got my code to work today. I don't know if it's the prettiest 
it can be, but it works:


// TESTING ACCESS TO the OWNING function
//---
class test_window
{
float x;
float y;

void draw_text(string text)
{
writeln(text);  
}

this( void function(test_window) onDraw  )
{   
this.onDraw = onDraw;
}

void run() //called every frame
{
onDraw(this);
}

void function (test_window) onDraw;
}


void test_dialog()
{
auto t = new test_window(function void(test_window ptr)
{
with(ptr)
{
draw_text( format("Hello, world. [x,y]=[%f,%f]", x, y));
}
});

t.run();
}





And a second attempt/version:





// TESTING ACCESS to anything
// --

struct data_to_access_t
{
int tacos;
}

struct data_to_access2_t
{
struct beans
{
int x;
};

beans b;
}

class abc(T)
{
int x;
void delegate(T) run_delegate;

T data;

this(T t, void delegate(T) d)
{
data = t;
run_delegate = d;
}

void execute()
{
run_delegate(data);
}
}

void test_dialog_anything()
{   
data_to_access_t  d;
data_to_access2_t d2;
d.tacos = 4;
d2.b.x  = 5;

	auto x = new abc!data_to_access_t ( d, (d) => writefln("test  
%d", d.tacos)  );
	auto y = new abc!data_to_access_t ( d, (d){writefln("test  %d", 
d.tacos);}  );
	auto z = new abc!data_to_access2_t(d2, delegate void 
(d2){writefln("test2 %d", d2.b.x);}  );


x.execute();
y.execute();
z.execute();
}





My only questions are:

 -  is there any way to make it "smart" enough to take the type 
of the argument, instead of me manually giving it a type.


	auto x = new abc!data_to_access_t ( d, (d) => writefln("test  
%d", d.tacos)  );

becomes
auto x = new abc( d, (d) => writefln("test  %d", d.tacos)  );

 - Is there any way to eliminate the first d? Which is 
essentially a "this" pointer.


	auto x = new abc!data_to_access_t ( d, (d) => writefln("test  
%d", d.tacos)  );

becomes
	auto x = new abc!data_to_access_t ( (d) => writefln("test  %d", 
d.tacos)  );


 - And preferably, if possible, both. But I'll take what I can 
get.


Re: Delegates and classes for custom code.

2018-04-17 Thread Simen Kjærås via Digitalmars-d-learn

On Tuesday, 17 April 2018 at 03:55:55 UTC, Chris Katko wrote:

What I want:

class viewport_t
  {
  int x,y,w,h;
  }

class dialog_t
  {
  int x,y;

  this( int x, int y, delegate void (viewport_t) on_draw )
{
this.x = x;
this.y = y;
this.execute = execute;
}

  void draw_text(string text)
{
}

  delegate void (viewport_t) on_draw;
  }

void function()
  {
  viewport_t v;
  dialog_t (15, 15,
delegate void (viewport_t)
  {
  draw_text("hello world"); //calls dialog_t function
  }
)
  }

Is this possible? Pass to a class, the code to run. But the 
code has to somehow know about the class methods.


I don't think you can pass "dialog_t.this" as it's being 
constructed!


Depending on exactly what you want to do, this may be impossible, 
or bauss' code might fit the bill, or you could use anonymous 
classes:



class viewport_t
{
int x,y,w,h;
}

class dialog_t
{
int x,y;

this( int x, int y)
{
this.x = x;
this.y = y;
}

void draw_text(string text)
{
}

abstract void on_draw(viewport_t);
}

void fn()
{
viewport_t v;
auto d = new class dialog_t {
this() { super(15,15); }
override void on_draw(viewport_t) {
draw_text("hello world");
}
};
}

--
  Simen


Re: Delegates and classes for custom code.

2018-04-17 Thread bauss via Digitalmars-d-learn

On Tuesday, 17 April 2018 at 03:55:55 UTC, Chris Katko wrote:

What I want:

class viewport_t
  {
  int x,y,w,h;
  }

class dialog_t
  {
  int x,y;

  this( int x, int y, delegate void (viewport_t) on_draw )
{
this.x = x;
this.y = y;
this.execute = execute;
}

  void draw_text(string text)
{
}

  delegate void (viewport_t) on_draw;
  }

void function()
  {
  viewport_t v;
  dialog_t (15, 15,
delegate void (viewport_t)
  {
  draw_text("hello world"); //calls dialog_t function
  }
)
  }

Is this possible? Pass to a class, the code to run. But the 
code has to somehow know about the class methods.


I don't think you can pass "dialog_t.this" as it's being 
constructed!


First of all your code is not valid D code.

To construct a delegate you use the following syntax:

RETURN_TYPE delegate(PARAMS);

Ex. in your case:

void delegate(viewport_t);

Secondly, classes are reference types and thus you cannot 
construct just like:


viewport_t v;

It must be assigned using "new".

Ex.

auto v = new viewport_t;

The same goes for your dialog_t instance.

What you can do to avoid double allocation of dialog_t is to 
initially set it to void and thus you can point to the initial 
variable within your delegate that is constructed when dialog_t 
is actually constructed.


Ex.

dialog_t d = void;
d = new dialog_t (15, 15,
  delegate void (viewport_t)
  {
  d.draw_text("hello world"); //calls dialog_t 
function

  }
);

I could go into more details, but that would be completely 
unrelated to your issue at hand.


Re: Delegates and classes for custom code.

2018-04-16 Thread Nathan S. via Digitalmars-d-learn

On Tuesday, 17 April 2018 at 04:09:57 UTC, Chris Katko wrote:
I'm having trouble conceptualizing this issue at the moment. 
But it seems if I pass to the delegate my object, then I can 
ONLY use one class type.


Can you post the code you're trying to run?


Re: Delegates and classes for custom code.

2018-04-16 Thread Chris Katko via Digitalmars-d-learn
I'm having trouble conceptualizing this issue at the moment. But 
it seems if I pass to the delegate my object, then I can ONLY use 
one class type.


Say, the delegate takes a "this" from... some class that wants to 
have a dialog. A window. Now the delegate NEEDS a this from a 
window, and only a window. So if I have a delegate in... 
something else, I'll either need to figure out some way for 
templates to work with that... or some kind of wrapping class / 
interface.


But all I want is a kind of Javascript'y:

Every time this object gets .onDraw() called. It does whatever I 
told it to do.


auto t = new object1( onDraw(){ do stuff} );
auto t2 = new object2( onDraw() { do other stuff} );

I'm trying to do the same kind of API for button handling where 
it automatically links into event queues (which works) and the 
button does whatever I want it to. But, it can only access PUBLIC 
INTERFACES (globals) because it can't access the underlying 
object and globals are the only ones it can statically figure out 
at compile-time.




Re: Delegates and classes for custom code.

2018-04-16 Thread Chris Katko via Digitalmars-d-learn

Some typos in there.

execute == on_draw.

Basically, I'm just sending a delegate/lambda "custom function" 
at initialization time. But I'd like that delegate to somehow 
access the holding classes functions. Or figure out how to do 
that.


Maybe the class somehow sends the delegate a this parameter when 
the class goes to execute it?


Delegates and classes for custom code.

2018-04-16 Thread Chris Katko via Digitalmars-d-learn

What I want:

class viewport_t
  {
  int x,y,w,h;
  }

class dialog_t
  {
  int x,y;

  this( int x, int y, delegate void (viewport_t) on_draw )
{
this.x = x;
this.y = y;
this.execute = execute;
}

  void draw_text(string text)
{
}

  delegate void (viewport_t) on_draw;
  }

void function()
  {
  viewport_t v;
  dialog_t (15, 15,
delegate void (viewport_t)
  {
  draw_text("hello world"); //calls dialog_t function
  }
)
  }

Is this possible? Pass to a class, the code to run. But the code 
has to somehow know about the class methods.


I don't think you can pass "dialog_t.this" as it's being 
constructed!