www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Delegate problem

reply Niall FitzGibbon <billdoor gmail.com> writes:
I have the following code, the purpose of which is to pass a callback 
delegate to an object of one class, in which it is stored, to be reused 
periodically by that class. Everything is fine until I actually come to 
call the delegate, at which point I get a seemingly nonsensical cast error:

renderer\text.d(225): cannot implicitly convert expression (spr) of type 
sprite to sprite
renderer\text.d(225): cast(sprite)(spr) is not an lvalue

The line that produce the error is:
bit draw = m_getcell(x, y, spr, darken, grey);

The code:

typedef uint sprite;

alias bit delegate(uint x, uint y, out sprite spr, out bit darken, out 
bit grey) viewportcallback;

class TextViewportWindow : TextWindow, IViewportWindow
{
public:
	this(Screen scr, uint x, uint y, uint width, uint height)
	{
		super(scr, x, y, width, height);
		m_vwidth = m_win.usablewidth;
		m_vheight = m_win.usableheight;
	}

	void setViewport(viewportcallback getcell)
	{
		m_getcell = getcell;
	}
	
	void render()
	{
		if(m_getcell is null)
			return;
		
		// update the window from the callback -- coordinates have 0,0 at centre
		int cx = m_vwidth / 2;
		int cy = m_vheight / 2;
		int topleftx = -cx;
		int toplefty = -cy;
		int bottomrightx = topleftx + m_vwidth;
		int bottomrighty = toplefty + m_vheight;
		for(int y = toplefty; y < bottomrighty; y++)
		{
			for(int x = topleftx; x < bottomrightx; x++)
			{
				sprite spr;
				bit darken = false;
				bit grey = false;
				bit draw = m_getcell(x, y, spr, darken, grey);
			}
		}

		if(m_win !is null)
		{
			m_win.redraw();
		}
	}

private:
	int m_vwidth;
	int m_vheight;
	
	viewportcallback m_getcell;
}

I just don't understand why it is trying to cast from sprite to sprite 
(and failing!). Any help would be greatly appreciated :)
Oct 16 2005
parent reply Marcello Gnani<marcello_gnani tiscali.it> writes:
Given your line:
alias bit delegate(uint x, uint y, out sprite spr, out bit darken, out bit grey)
viewportcallback;

I think you should then change the line:
bit draw = m_getcell(x, y, spr, darken, grey);

to:
bit draw = m_getcell(x, y,out spr,out darken,out grey);

but be warned: I may be wrong and i have no time to test it yet!


Marcello Gnani
<marcello_gnani tiscali.it>

In article <diufmi$2fa2$1 digitaldaemon.com>, Niall FitzGibbon says...
I have the following code, the purpose of which is to pass a callback 
delegate to an object of one class, in which it is stored, to be reused 
periodically by that class. Everything is fine until I actually come to 
call the delegate, at which point I get a seemingly nonsensical cast error:

renderer\text.d(225): cannot implicitly convert expression (spr) of type 
sprite to sprite
renderer\text.d(225): cast(sprite)(spr) is not an lvalue

The line that produce the error is:
bit draw = m_getcell(x, y, spr, darken, grey);

The code:

typedef uint sprite;

alias bit delegate(uint x, uint y, out sprite spr, out bit darken, out 
bit grey) viewportcallback;

class TextViewportWindow : TextWindow, IViewportWindow
{
public:
	this(Screen scr, uint x, uint y, uint width, uint height)
	{
		super(scr, x, y, width, height);
		m_vwidth = m_win.usablewidth;
		m_vheight = m_win.usableheight;
	}

	void setViewport(viewportcallback getcell)
	{
		m_getcell = getcell;
	}
	
	void render()
	{
		if(m_getcell is null)
			return;
		
		// update the window from the callback -- coordinates have 0,0 at centre
		int cx = m_vwidth / 2;
		int cy = m_vheight / 2;
		int topleftx = -cx;
		int toplefty = -cy;
		int bottomrightx = topleftx + m_vwidth;
		int bottomrighty = toplefty + m_vheight;
		for(int y = toplefty; y < bottomrighty; y++)
		{
			for(int x = topleftx; x < bottomrightx; x++)
			{
				sprite spr;
				bit darken = false;
				bit grey = false;
				bit draw = m_getcell(x, y, spr, darken, grey);
			}
		}

		if(m_win !is null)
		{
			m_win.redraw();
		}
	}

private:
	int m_vwidth;
	int m_vheight;
	
	viewportcallback m_getcell;
}

I just don't understand why it is trying to cast from sprite to sprite 
(and failing!). Any help would be greatly appreciated :)
Oct 17 2005
parent reply "Regan Heath" <regan netwin.co.nz> writes:
On Mon, 17 Oct 2005 09:13:56 +0000 (UTC), Marcello Gnani  
<marcello_gnani tiscali.it> wrote:
 Given your line:
 alias bit delegate(uint x, uint y, out sprite spr, out bit darken, out  
 bit grey)
 viewportcallback;

 I think you should then change the line:
 bit draw = m_getcell(x, y, spr, darken, grey);

 to:
 bit draw = m_getcell(x, y,out spr,out darken,out grey);

 but be warned: I may be wrong and i have no time to test it yet!
I don't think this is the problem. I'm not even sure if that is valid D syntax (though it was suggested at one stage). I took the code posted and made something that would compile. I did this by adding stub functions/classes/interfaces and so on, the result was code that compiled without any errors. So.. I suspect a bug is caused by code you didn't post. I suspect DMD is getting confused with something and giving a confusing error as a result. You should attempt to create a cut down example which compiles and exhibits the problem. To do this start with a copy of the real thing and cut large blocks of code out until it stops occuring, then add the last cut back in and cut something else. Post the resulting code, the smaller it is the faster Walter is likely to fix it. If it's not small someone else might be able to cut it down further. Here is the code I produced: typedef uint sprite; alias bit delegate(uint x, uint y, out sprite spr, out bit darken, out bit grey) viewportcallback; class TextWindow { this(Screen scr, uint x, uint y, uint width, uint height) {} Screen m_win; } class Screen { int usablewidth; int usableheight; void redraw() {} } interface IViewportWindow {} class TextViewportWindow : TextWindow, IViewportWindow { public: this(Screen scr, uint x, uint y, uint width, uint height) { super(scr, x, y, width, height); m_vwidth = m_win.usablewidth; m_vheight = m_win.usableheight; } void setViewport(viewportcallback getcell) { m_getcell = getcell; } void render() { if(m_getcell is null) return; // update the window from the callback -- coordinates have 0,0 at centre int cx = m_vwidth / 2; int cy = m_vheight / 2; int topleftx = -cx; int toplefty = -cy; int bottomrightx = topleftx + m_vwidth; int bottomrighty = toplefty + m_vheight; for(int y = toplefty; y < bottomrighty; y++) { for(int x = topleftx; x < bottomrightx; x++) { sprite spr; bit darken = false; bit grey = false; bit draw = m_getcell(x, y, spr, darken, grey); } } if(m_win !is null) { m_win.redraw(); } } private: int m_vwidth; int m_vheight; viewportcallback m_getcell; } void main() { TextViewportWindow a = new TextViewportWindow(new Screen(),0,0,100,100); a.render(); }
Oct 17 2005
parent Niall FitzGibbon <billdoor gmail.com> writes:
 So.. I suspect a bug is caused by code you didn't post. I suspect DMD is 
 getting confused with something and giving a confusing error as a 
 result. You should attempt to create a cut down example which compiles 
 and exhibits the problem.
 
 To do this start with a copy of the real thing and cut large blocks of 
 code out until it stops occuring, then add the last cut back in and cut 
 something else. Post the resulting code, the smaller it is the faster 
 Walter is likely to fix it. If it's not small someone else might be able 
 to cut it down further.
 
 Here is the code I produced:
Thanks. The code I posted was actually taken from two separate modules, so I imagine that is confusing the compiler somewhere. I'm going to try to shift blocks around between the two files until it compiles, using your version as a guide. When (if) I get it working, I'll post what the cause of the bug was. :)
Oct 17 2005