Jump to content
  • Advertisement
Sign in to follow this  
Waaayoff

Design pattern for linking UI events to editor code?

This topic is 1088 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

When I started writing my terrain editor, I had few UI events so I just had their IDs stored in an enum and called a function to process the event in my editor whenever the event occured. As the number and type of events grew, the code became messy. Basically a giant nested switch statement.

 

What would be a good way to handle this situation? I have various event types such as:

- Setting parameters (floats, integers, bools, strings, etc..)

- Changing render modes / view modes / paint modes

- 'Orders' such as new, load, save, etc...

 

And then there is of course the fact that this has to be general enough to be integrated with an Undo/Redo system.

Share this post


Link to post
Share on other sites
Advertisement

Command pattern might be what you are looking for, it separates all actions into different classes and supports undo-commands (though you still have to implement the undo-operation yourself, unless you store the whole games state and copy/store that for every undo command...).

Share this post


Link to post
Share on other sites

But then wouldn't you end up with a large amount of command classes?

 

class SetBrushRadius : public ICommand;

class SetBrushStrength : public ICommand;

class SetBrushType : public ICommand;

etc...

 

And if you choose to have a single class called SetParameter instead, you'd still have to do a giant if statement inside to determine which parameter to set.

Edited by Waaayoff

Share this post


Link to post
Share on other sites

But then wouldn't you end up with a large amount of command classes?

 

Depends. Generally yes, but you are not going to avoid that alltogether. Its way better to have a lot of classes then a giant if statements because 1) the classes are independant of each other and thus 2) all the classes can be organized and managed better. You still have to realize that if you have different parameters that you want to couple to your UI, you will at least have to write SOME code for letting your application know that this parameter exists and what to do with it.

 

But if you want to reduce the amount of code for parameters, here is what you can do. Instead of writing a different class for each parameter, you use a template class (for the type) and store a function pointer:

template<typename Type, typename Object>
class ParameterCommand : public ICommand
{
	using FunctionPointer = void ()(Type);
public:
	ParameterCommand(Type value, Object& targetObject, FunctionPointer targetFunction),
		pTargetObject(&targetObject), targetFunction(targetFunction)
	{
	}
	
private:
	
	Type value;
	TargetObject* pTargetObject;

	FunctionPointer targetFunction;
	
}

And then you can just do:

ParameterCommand<float, Brush> radiusCommand(5.0, brush, &Brush::SetRadius);

This is just an example and might not even perfectly fit your use-case, but you get the idea. Command pattern, unlike your nested if-list, allows you to use all the class/template magic of C++ to reduce the amount of things you have to write. But you have to write some code for each parameter... wait, you are using C++, right? There might be even easier tools in other languages based on reflection, but command pattern is still a viable top-level solution which allows you to solve the specific subsets of your problem the way that your language makes it the easiest.

 

On an unrelated note, was the brush-example an artifical example or do you really plan on making those undoable too? I'd advice against it, I hate nothing more than wanting to undo a series of changes I made, and having the application undo all my brush/tool changes in the mix. Might be personal opinion but not many applications even do that which I've seen.

Edited by Juliean

Share this post


Link to post
Share on other sites

I do like the template and function pointer approach. I think I will check just how many parameters I will have at the end and see if the extra complexity is worth it.

 


On an unrelated note, was the brush-example an artifical example or do you really plan on making those undoable too? I'd advice against it, I hate nothing more than wanting to undo a series of changes I made, and having the application undo all my brush/tool changes in the mix. Might be personal opinion but not many applications even do that which I've seen.

 

I didn't think about that. You're right I think I'll only undo actual changes to the terrain. So set parameter and similar commands won't be put on the Undo stack.

Share this post


Link to post
Share on other sites


When I started writing my terrain editor, I had few UI events so I just had their IDs stored in an enum and called a function to process the event in my editor whenever the event occured. As the number and type of events grew, the code became messy. Basically a giant nested switch statement.

 

When I read your question and this part, my first thought was MVVM. But I seem to be wrong in that assumption.

Share this post


Link to post
Share on other sites

You might be able to consolidate multiple command objects into the same class (or the same function, using techniques like Julean's template), initialized in different ways.

For example, a AlterBrushCommand class containing all brush parameters as members could be equipped with with chainable setters or something of the sort and used to change any combination (usually only one) of radius, strength, type etc.(e.g. executing new AlterBrushCommand(currentBrush).radius(brushRadiusSlider.currentValue()), new AlterBrushCommand(currentBrush).type(brushTypeSelector.currentValue()), and so on),

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!