FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Extending D classes in MiniD

 
Post new topic   Reply to topic     Forum Index -> MiniD
View previous topic :: View next topic  
Author Message
simhau



Joined: 06 Feb 2007
Posts: 55

PostPosted: Sun Jan 13, 2008 5:36 pm    Post subject: Extending D classes in MiniD Reply with quote

Is this actually possible..?

I have a UI for SDL written in D, and I want MiniD to control everything. Now the application just launches a MiniD script and lets MiniD have full control.

But I want to be able to extend my classes so I can override the events, but I get an error when I'm testing this...

MapView.constructor(native): MDValue.to() - Cannot convert 'instance of class MyMapView' to 'WrappedInstance'

Is there some way of achieving this without too much work?
Back to top
View user's profile Send private message
simhau



Joined: 06 Feb 2007
Posts: 55

PostPosted: Sun Jan 13, 2008 9:51 pm    Post subject: Reply with quote

I've almost found a workaround for my event problems..

I just need to know how I can manually convert between my D type and the wrapped MiniD type.

I tried using the ToMiniDType from bind.d, but I wasn't allowed...
I bet theres a simple way of doing this, but I couldn't find it in the documentation, and theres quite a lot code to browse.
Back to top
View user's profile Send private message
JarrettBillingsley



Joined: 20 Jun 2006
Posts: 457
Location: Pennsylvania!

PostPosted: Sun Jan 13, 2008 11:08 pm    Post subject: Reply with quote

Extending wrapped D classes in MiniD might seem to work in some cases, but there are some serious issues with it. Namely, if you have a class A that you derive from and override a method of in MiniD, when a native function that takes an A calls that overridden method, it won't call the method that was declared in MiniD, it'll call the base class (A's) method. Basically the problem is: what state do you call that overridden method in? The native method isn't passed a state parameter, and it might not even know anything about MiniD at all (like in a lib not written expressly for use with MiniD). Pyd doesn't have any problem with this case because there is only one global interpreter in Python. This is unsolvable without some serious changes in the way the interpreter works and is something I really want to rectify for MiniD 2.
Back to top
View user's profile Send private message
simhau



Joined: 06 Feb 2007
Posts: 55

PostPosted: Mon Jan 14, 2008 6:23 am    Post subject: Reply with quote

I see. It would have been really useful, so I hope you are able to sort out those issues for MD2.

As I said, I think I have a workaround for my event handling.
I've added some functions to my widget class that takes an MDClosure as a parameter. This is then added in my event signal class just as delegates and functions is. This will allow me to use MiniD for event handling, but my problem is passing parameters to the MiniD function...

The callbacks is called with two classes, the Widget that raised the event, and an Event class containing data. Both these classes are wrapped in MiniD, but when using MDContext.easyCall() I need to send instances of MDValue.

I don't know how I can convert my native D classes to the wrapped MiniD types.


This is not optimal as I don't want these classes to know about MiniD, but it's more important that I can actually use MiniD with my library Smile
Back to top
View user's profile Send private message
JarrettBillingsley



Joined: 20 Jun 2006
Posts: 457
Location: Pennsylvania!

PostPosted: Mon Jan 14, 2008 7:18 am    Post subject: Reply with quote

Go ahead and make the ToDType and ToMiniDType functions public; there was a reason I made them private in the first place but to be honest I can't remember what it was Rolling Eyes

The binding library is admittedly one of the weaker parts of the library, sorry I haven't worked on it that much.
Back to top
View user's profile Send private message
simhau



Joined: 06 Feb 2007
Posts: 55

PostPosted: Mon Jan 14, 2008 8:10 am    Post subject: Reply with quote

Yeah, I figured the binding library is a bit lacking.

When wrapping derived classes I couldn't find a way to ensure methods and properties wrapped in the base class automatically gets wrapped... It's a bit tedious and error prone to wrap all base class functionality for all derived classes.

Guess the binding library is going to be redesigned again for MD2?
Back to top
View user's profile Send private message
JarrettBillingsley



Joined: 20 Jun 2006
Posts: 457
Location: Pennsylvania!

PostPosted: Mon Jan 14, 2008 10:16 am    Post subject: Reply with quote

Derived classes will inherit everything from their base class. That's guaranteed.
Back to top
View user's profile Send private message
simhau



Joined: 06 Feb 2007
Posts: 55

PostPosted: Mon Jan 14, 2008 11:07 am    Post subject: Reply with quote

I cannot get it to work

Code:
module test;

import tango.io.Stdout;

import minid.minid;
import minid.bind;
import minid.types;

class B {
   int i() { return _i; }
   void i(int i) { _i = i; }

   protected:
   int _i;
}

class D : B {
   int y() { return _y; }
   void y(int y) { _y = y; }

   protected:
   int _y;
}

void main()
{
   auto ctx = NewContext(
      MDStdlib.Array
      | MDStdlib.Char
      | MDStdlib.Math
      | MDStdlib.String
      | MDStdlib.Table);

   WrapModule("test", ctx)
      .type(WrapClass!(B)()
         .property!(B.i)()
      )
      .type(WrapClass!(D)()
         .property!(D.y)()
      )
   ;

   try {
      Stdout.formatln("Loading script");
      ctx.importModule("mdtest"d);
   } catch(MDException e) {
      Stdout.formatln("Error: {}\n{}", e.toString(), ctx.getTracebackString());
   }
   Stdout.formatln("Script finished");
}



Code:
module mdtest;
import test : B, D;

local b = B();
b.i(1);
writefln("B.i=", b.i());

local d = D();
d.y(2);
writefln("D.y=", d.y());
d.i(1);
writefln("D.i=", d.i());


This outputs

Loading script
B.i=1
D.y=2
Error: Error loading module "mdtest":
mdtest.module mdtest(11:25): Attempting to access nonexistent member 'i' from class instance
Traceback: mdtest.module mdtest(11:25)
Script finished
Back to top
View user's profile Send private message
JarrettBillingsley



Joined: 20 Jun 2006
Posts: 457
Location: Pennsylvania!

PostPosted: Mon Jan 14, 2008 2:24 pm    Post subject: Reply with quote

OK, that's odd, it's not minid.bind that broken but for some reason it wraps D before it wraps B when the module is loaded, so B isn't found as the base class for D. I would have expected the chained methods to be executed left-to-right.

A simple fix:

Code:
with(WrapModule("test", ctx))
{
    type(WrapClass!(B)()
        .property!(B.i)()
    );
    type(WrapClass!(D)()
        .property!(D.y)()
    );
}


I'll have to do some more testing to see why the chained methods are getting called in reverse order.. I mean, it doesn't do that when using i.e. Tango IO!
Back to top
View user's profile Send private message
JarrettBillingsley



Joined: 20 Jun 2006
Posts: 457
Location: Pennsylvania!

PostPosted: Mon Jan 14, 2008 2:52 pm    Post subject: Reply with quote

OK, with some more testing, it's not that the methods are being called backwards, it's that their arguments are being evaluated backwards before they're even called. Big WTF moment there.

Code:
WrapModule("blah", ctx).type(WrapClass!(A)()).type(WrapClass!(B)());


happens in the following order:

  1. temp b = WrapClass!(B)()
  2. temp a = WrapClass!(A)()
  3. temp m = WrapModule("blah", ctx)
  4. m.type(a)
  5. m.type(b)


So even though the methods are called in the correct order, their params are evaluated before they're called in the wrong order.

Scary corner cases in order-of-evaluation.
Back to top
View user's profile Send private message
simhau



Joined: 06 Feb 2007
Posts: 55

PostPosted: Tue Jan 15, 2008 6:08 am    Post subject: Reply with quote

Aha.

This deserves some documentation. It's more natural to start by wrapping baseclasses, so I guess I'm not the only one getting this behaviour.
Back to top
View user's profile Send private message
csauls



Joined: 27 Mar 2004
Posts: 278

PostPosted: Tue Jan 15, 2008 9:26 pm    Post subject: Reply with quote

I find this rather surprising... I would expect code generation to follow the order of data necessity; which in your example and list would seem to be numbers 3, 2, 4, 1, then 5. Quite a difference!

Its just this sort of occasional bump in the road that motivates me to test every micro-design with some short throw-away program first. This is one of those 'corner cases' that you may want to make sure you mention in the MiniD docs -- since I'm sure it will come up again and again as it gains more usage.

And it might not hurt to get an explanation on why it occurs in this order.
_________________
Chris Nicholson-Sauls
Back to top
View user's profile Send private message AIM Address Yahoo Messenger
JarrettBillingsley



Joined: 20 Jun 2006
Posts: 457
Location: Pennsylvania!

PostPosted: Wed Jan 16, 2008 9:02 am    Post subject: Reply with quote

Posted on the D NG.
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic     Forum Index -> MiniD All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group