Trending
Opinion: How will Project 2025 impact game developers?
The Heritage Foundation's manifesto for the possible next administration could do great harm to many, including large portions of the game development community.
Delegates are a very useful design pattern. Here I show a concrete example of how I use delegates.
[From PompiDev blog]
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.
Read more about:
BlogsYou May Also Like