I like delegates (Input example)

December 26th, 2009 by ofer
Posted in Coding, The RPG Game

Delegates are a very powerful design pattern, that come in a variety of forms and can solve a large variety of problems. A simple way to describe delegate would be with some code:

class Base {
	public:
		virtual void foo() = 0;
		virtual ~Base(){};
};

class A: public Base {
	public:
		void foo() {...};
};

class B: public Base {
	public:
		void Initialize (Base & d) { this->d = &d; };
		void foo() {...; this->d->foo(); };
	private:
		Base * d;
};

 

As you can see, class B can use class A’s functionality by pointing to it. But what is it good for? Here is a more concrete example.

class BaseTextKeyboard: virtual public BaseClass {
	public:
		virtual void Enable() = 0;
		virtual void Disable() = 0;
		virtual void ClearText() = 0;
		virtual std::string GetText() = 0;
};

class WindowsKeyboard: public BaseWindowsKeyboard, public BaseTextKeyboard {
	public:
		void Enable();
		void Disable();
		void TranslateMessage (WPARAM wParam, LPARAM lParam);
		void ClearText();
		std::string GetText();
		WindowsKeyboard();
};

class TextKeyboard: public BaseTextKeyboard {
	public:
		void Enable();
		void Disable();
		void Initialize (GetKeyKeyboard & A_Keyboard);
		void ClearText();
		void Handle();
		std::string GetText();
		TextKeyboard();
};

class TextKeyboardFeeder: public BaseTextKeyboard {
	public:
		void Initialize (BaseTextKeyboard & A_Delegate);
		void Enable();
		void Disable();
		void ClearText();
		std::string GetText();
		void Handle();
		TextKeyboardFeeder();
	private:
		bool IsEnable;
		std::string Text;
		BaseTextKeyboard * Delegate;
};

I needed to have text input in TRG’s GUI. A line which you can type text, like in a text field in a web form. At first I thought to use direct input for the job. Since I already had some code for direct input and keyboard. I created a class called TextKeyboard, and I had another class for the text field that used it. I quickly found out that reading keyboard is not trivial. You need to deal with shift being pressed, with keys being held down. All this is already dealt with when you process a window message called WM_CHAR, which makes it pointless to achieve the same functionality using direct input.

Since I already wrote the text field class, I wanted to write the “windows keyboard” in a way I could just send it to the text field class and it would work. I then created a base class(BaseTextKeyboard), or an interface for the TextKeyboard which contained virtual methods and only those that are used with the text field.
I then created a class called WindowsKeyboard which implemented BaseTextKeyboard. However, there was a problem. TextKeyboard was created once for every text field, but WindowsKeyboard could only be created once for all the text fields. Every text field was pointing to the same WindowsKeyboard, which made things not to work properly.

The solution? Have a TextKeyboardFeeder class. This class will both implement the BaseTextKeyboard interface and will point to a WindowsKeyboard class. TextKeyboardFeeder will be created once for every text field, and will have it’s own std:string. Only when the text field is in focus, the corresponding TextKeyboardFeeder will read from the WindowsKeyboard class.
We have another layer of feeders that point to the actual WindowsKeyboard. Each text field has it’s own copy of TextKeyboardFeeder. Each feeder copy has it’s own std:string that contains keyboard input, but all the feeders point to the same WindowsKeyboard and read the text input from it.
By the way, since TextKeyboardFeeder point to BaseTextKeyboard, it could also point to TextKeyboard instead of WindowsKeyboard and it would also work. That is the power of delegates.

Is it clear what I was doing? Do you wish to see more code? More detailed explanation? Please reply and tell me what you think.

Share and Enjoy:
  • Print
  • Digg
  • Sphinn
  • del.icio.us
  • Facebook
  • Mixx
  • Google Bookmarks

Recursive Development

December 22nd, 2009 by ofer
Posted in Coding, The RPG Game

I have been working on a little language to represent GUI objects placement for the TRG project.
This allows me to write a text file with a certain format and syntax, so the game will be able to parse it and place the GUI objects on the screen. It allows changing the GUI without recompilation and removes the need to hard code some of the GUI logic inside the C++ project. I also plan to build a tool that will allow me to drag and drop GUI objects on the screen, and to save it into such text file.
Here is an example of an early stage of the parsed GUI, first the result and then the GUI text file:

GUI Example

GUI Example

Draw4Text (x, y, dy, n)
{
	Text (x, y, "Text "+n+".1");
	Text (x, y+dy, "Text "+n+".2");
	Text (x, y+dy+dy, "Text "+n+".3");
	Text (x, y+dy+dy+dy, "Text "+n+".4");
}

Error1 ()
{
	Draw4Batch (512, 384, 30);
}

Draw4Batch (x, y, dy)
{
	Draw4Text (x, y, dy, 1);
	Draw4Text (x, y+dy+dy+dy+dy, dy, 2);
}

Error2 (a)
{
	Error ("Testing error number 2");
}

The problem? I don’t know what I want to have in TRG’s GUI yet. I believe it’s better to develop code around “real life situations”, rather than guessing what features I will need. My solution is to use the tool as an example of the requirements from the little language. With the tool I will be able to build GUIs, but the tool itself need to have a GUI. I will build the GUI of the tool with a text file, and after I will have the first version of the tool, I will build the next version of the tool’s GUI with the earlier version. Sort of a recursive development. The tool will be used as both an example of what I need and both as the tool to create the next iteration.
It is a sort of a compromise, but I think it’s better than just guessing.

Share and Enjoy:
  • Print
  • Digg
  • Sphinn
  • del.icio.us
  • Facebook
  • Mixx
  • Google Bookmarks

Minimizing “thought resources”

December 18th, 2009 by ofer
Posted in Coding

It can be fun to think hard about something. But sometimes we waste a lot more thought than we could to achieve the same goal and even better. Let’s say that efficient use of thought resources is to choose the path that requires you the minimum thinking and effort to achieve the same goal or better.
I will try to bring a metaphor, because I am afraid a math or code example would be less intuitive.
Let’s say you need to carry rocks from one place to another. You can pick them one by one, by hand, and carry them. In some cases this will be the best solution, but what if you need to carry rocks every day for the whole year? Wouldn’t it be better to build or buy a wheelbarrow? Though, if you needed to carry a few works than maybe getting a wheelbarrow is not worthwhile.

In programming this can mean planning ahead how you are going to solve a problem, or researching for the right existing technology to use.
However, things are not as simple as that. Planning consume thought resources or effort. You might end up planning too much ahead or investing long hours in planning something you don’t really know if it will work. This means there need to be a balance between planning and just trying things out. It might sound funny, but I believe you don’t want to sweat too much most of the time you code. A game requires large amounts of code and work, and if every minute of it would require you a lot of thought and effort, you will quickly burn out. A lot of the time coding should be easy or with very little effort. Of course, sometimes it’s tough. And sometimes it gets really tough, but you want to minimize the times it gets really tough.

The thing that inspired me to write this article is some code I had to write to build a tree from a data structure. This data structure is the result of a text file I parsed with boost::spirit(more about that in future post). In my first attempt I simply used a tool I had available, of building a tree. I forgot I had another tool built upon it that would make my life much easier.
The basic tool would call two virtual methods, build child and build sibling, and with those you are suppose to build the tree. The code I wrote for this tool was long, ugly and didn’t work. After this failed attempt I realized I have a tool I built upon the basic tool. This tool allows me to add the edges of the tree. I have an AddEdge method that gets parent index, child index and node data. The implementation make sure all those edges I add will create a tree after I call BuildTree. A lot simpler.
The first code snippet is of the advanced tree building tool, and the second code snippet is of the basic building tool. Notice the code is not spartanized much, and you don’t really need to try and understand it. Just try to see which one looks prettier. You might not see the code if you are not at the original blog website(because it’s a lot of code, and because of different plug-ins), so for the code you should visit my blog.

	void
	NodeFunction::NodeFunctionCall::AddNode (MathNode n, DWORD A_Parent, DWORD A_ListIndex, Tree::Builder & b)
	{
		using boost::fusion::at_c;
		this->CurrentIndex++;
		DWORD i = this->CurrentIndex;
		if (at_c<1>(n.Node).size()!=0)
		{
			NodeFunction::NodeFunctionCall::ParameterNode NodeData;

			NodeData.IsOperation = true;
			NodeData.Operation = at_c<0>((at_c<1>(n.Node))[A_ListIndex]);
			b.AddEdge (A_Parent, i, NodeData);
			if (A_ListIndex==0)
				this->AddSingleNode (at_c<0>(n.Node).get(), i, b);
			else
				this->AddSingleNode (at_c<1>((at_c<1>(n.Node))[A_ListIndex-1]).get(), i, b);
			if (A_ListIndex+1==at_c<1>(n.Node).size())
				this->AddSingleNode (at_c<1>((at_c<1>(n.Node))[A_ListIndex]).get(), i, b);
			else
				this->AddNode (n, A_Parent, A_ListIndex+1, b);
			return;
		}
		this->AddSingleNode (at_c<0>(n.Node).get(), A_Parent, b);
	}

Basic tree builder code.

	MemberClass >
	NodeFunction::NodeFunctionCall::Builder::CreateNode (MathNode A_Node, MathNode A_ExtraNode, DWORD A_Index, bool A_ExtraSibling)
	{
		MemberClass > Result;

		NodeFunction::NodeFunctionCall::ParameterNode NodeData;

		Result->bCreate = false;
		bool IsExtraSibling = false;

		if (A_Index!=0 && A_ExtraSibling && (A_Index-1)==boost::fusion::at_c<1>(A_Node.Node).size())
		{
			IsExtraSibling = true;
			A_Index = 0;
			A_Node = A_ExtraNode;
			A_ExtraSibling = false;
		}

		while (boost::fusion::at_c<1>(A_Node.Node).size()==0)
		{
			MathSingleNodeType * SingleNode = &(boost::fusion::at_c<0>(A_Node.Node).get().Node);
			boost::recursive_wrapper * p = boost::get >(SingleNode);
			if (p==NULL)
			{
				Result = this->CreateSingleNode (boost::fusion::at_c<0>(A_Node.Node).get());
				if (IsExtraSibling)
					Result->Data.IsSibling = false;
				return Result;
			}
			A_Node = p->get();
		};

		if (A_Index(A_Node.Node).size())
		{
			ComplexNode c = boost::fusion::at_c<1>(A_Node.Node);
			NodeData.IsOperation = true;
			NodeData.Operation = boost::fusion::at_c<0>(c[A_Index]);
			NodeFunction::NodeFunctionCall::BuilderData b;
			b.IsSibling = true;//!IsLast || A_ExtraSibling;
			boost::recursive_wrapper * Single = A_Index==0?&boost::fusion::at_c<0>(A_Node.Node):&boost::fusion::at_c<1>(c[A_Index-1]);
			MathSingleNode n = Single->get();
			if (boost::get >(&n.Node)!=NULL)
				b.Node = boost::get >(n.Node).get();
			else
			{
				MathNode m;
				boost::fusion::at_c<0>(m.Node) = *Single;
				b.Node = m;
				if (A_Index==0 && !IsExtraSibling)
					b.IsSibling = false;
			}
			bool IsLast = A_Index==boost::fusion::at_c<1>(A_Node.Node).size()-1;
			b.IsNull = false;
			b.Index = A_Index;
			if (IsLast)
			{
				b.IsExtra = true;
   				boost::recursive_wrapper * Single = &boost::fusion::at_c<1>(c[A_Index]);
				n = Single->get();
				if (boost::get >(&n.Node)!=NULL)
					b.ExtraNode = boost::get >(n.Node).get();
				else
				{
					MathNode m;
					boost::fusion::at_c<0>(m.Node) = *Single;
					b.ExtraNode = m;
				}
			}
			Result->bCreate = true;
			Result->NodeData = NodeData;
			Result->Data = b;
			return Result;
		}
		GlobalErrorWrap::Assert (false, "Unreachable ParsedGUI build code");
		return Result;
	}

Share and Enjoy:
  • Print
  • Digg
  • Sphinn
  • del.icio.us
  • Facebook
  • Mixx
  • Google Bookmarks

Learning and #include

December 11th, 2009 by ofer
Posted in Other blogs

In C++ you can roughly divide code files into two types. Implementation files(.cpp) and header\definitions files (.h). The header files can include other header files, which mean you have some sort of a graph depicting the includes “web” of the headers. You cannot have cyclic inclusion of headers. The header files are used to make class and function definitions, which allow other files(.h or .cpp) to use these classes/functions as well.
I want to ask you some questions, and I want you to think of the answers before you keep on reading. Even if you don’t know C++, try to think of answers. There is no penalty for giving a “wrong” answer, just try to honestly answer these questions.

  1. What is the potential problem of having a header include many other headers?
  2. Why it can be good to include directly all the necessary headers instead of including a header that include the necessary headers?
  3. What is the potential problem of having many headers include the same header?

My answers to these questions are not the “correct” answers, they are also not the only answers. These are just things I have learned from experience, and they were right for me at least at one moment and situation.
The potential problem with having a header include many headers is because of compilation. If you include many headers, each time you change one of those headers, you will need to recompile everything that include this header. Which means almost every time you change the program, you will need to compile a lot of things.
Including the necessarily files directly is good when you want to remove a specific header file from your project. Because otherwise you might need to start figuring out what more you need to include in a file that included the header you want to remove.
When a lot of files include a specific header, removing that header might require removing all those file that include it. This make sense and is how things work. But things might get problematic when a header file contains two “subjects”, one that you want to remove and the other that you don’t want to remove. In this case you need to split up this file.

What does all this got to do with learning? I just recently completed and released Labyrinthica: The quest of lima, and started to work on a new project. I wanted to use some of the files from Labyrinthica in the new project, but I wanted to remove some files which were not relevant to this project. This made me encounter some of the problems above, and made me learn by example or learn from mistake. People remember much better when they learn from a mistake
This is backed up by studies and research. I have already been told by other developers about good practices with header files, a million of times. But only when I experienced the problem myself, I got an in depth understanding of the problem.
Programming is a bit different than giving an incorrect answer. Because programming is not 100% formal, problems in programming can have many different solutions and no one correct answer. But still, you learn how to program by sitting down and trying to code. Some people might try to find the perfect solution to a problem they never solved before. They end up thinking about it for months, But never trying to actually sit and code. Sometimes you need to look for the simplest solution, without knowing if it will really succeed or if this solution won’t really solve the problem. If this solution works, good. If it doesn’t, then you will have better understanding of the problem you tried to solve, and in the next attempt you are more likely to solve it.

And lastely, here is a research I have found by looking at Yahoo news. Link.

Share and Enjoy:
  • Print
  • Digg
  • Sphinn
  • del.icio.us
  • Facebook
  • Mixx
  • Google Bookmarks

Project “TRG(The RPG Game)” and other active projects.

December 6th, 2009 by ofer
Posted in Other blogs, The RPG Game

I currently have 3 active projects.
Labyrinthica: The quest of lima, is complete but I intend to improve it and fix problems. There is a problem in case someone has a new graphics card and an additional old graphics card. Labyrinthica would shout about the old graphics card and won’t let the game run. There is also a need to add instructions in the game, especially for the potions system. Since it’s pretty unclear to new players. I also need to promote and get exposure for Labyrinthica. In a sense, from now on Labyrinthica will always be an active project.

The second project is Banana Jump, Barrel Kick. The windows version is almost complete, the main thing I need to do is draw the artwork.

The third project is a new project. For now I will call it project TRG(The RPG Game). This game will be a 2D RPG game, single\multi player. I have a good feeling about this project. The game will use a lot of the code used in Labyrinthica, this means that if I improve the core code of this game, I will also improve the core code of Labyrinthica.

Share and Enjoy:
  • Print
  • Digg
  • Sphinn
  • del.icio.us
  • Facebook
  • Mixx
  • Google Bookmarks