Thread overview
Delegate problem
Oct 16, 2005
Niall FitzGibbon
Oct 17, 2005
Marcello Gnani
Oct 17, 2005
Regan Heath
Oct 17, 2005
Niall FitzGibbon
October 16, 2005
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 :)
October 17, 2005
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 :)


October 17, 2005
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();
}
October 17, 2005
> 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. :)