I have a class AwesomeMousePointer that has some function to start playing animations on the mouse:
class AwesomeMousePointer{
void startAnimat();
void stopAnimat();
};
I have another object to which I have given the responsibility of figuring out whether the mouse anims should start or not (this is based on the internal hit testing on the object, for eg: if the mouse is inside the object for a specific time)
class SomeShape(){
Event<MouseArgs> startAnim
Event<bool> interrutptAnim
bool hitTest(int x, int y);
//Inside some loop function, check if the mouse is inside the object
if(hitTest(mouseXPos, mouseYPos)){
//if the mouse if inside for x time
NotiftyEvent(startAnim, MouseArgs);
}
else{
//mouse left the object
NotifyEvent(interruptAnim, false);
}
Now, again inside my AwesomeMousePointer, I'll add listeners for the events i.e
AddListener(SomeShape::startAnim, &AwesomeMousePointer::startAnim);
AddListener(SomeShape::interruptAnim, &AweseommousePointer::interruptAnim);
The single event system by using NotifyEvent and AddListener are working correctly in short different example I tried. Now inside this application of mine, I have a lot of the objects of SomeShape and a single AwesomeMousePointer. My question is if the above logic for the anims will work or should I explicitly pass the SomeShape object explicitly to subscribe to their events, in which things would become a bit difficult.
For eg:
AddListener(shapeObject1.startAnim, &AwesomeMousePointer::startAnimat);
AddListener(shapeObject2.startAnim, &AwesomeMousePointer::startAnimat);
AddListener(shapeObject3.startAnim, &AwesomeMousePointer::startAnimat);
OR
AddListener(SomeShape::startAnim, &AwesomeMousePointer::startAnimat);
Will the second one from the above work out? If not, how will that be done without explicitly passing the object since that makes the unclear and ShapeObjects shouldn't be inside the MousePointer.
Will this work if I make the events inside SomeShape as static?
static Event<MouseArgs> startAnim
static Event<bool> interrutptAnim
You say that you don't want to have coupling between the senders and targets. In this case, usage of Poco events is not appropriate. According to http://pocoproject.org/slides/090-NotificationsEvents.pdf, you should use Notifications instead of Events, because your senders and targets do not need to know each other then.
Related
The UI system in my program currently works by assigning function pointers of the type void(*)() to trigger elements (quads on the screen, keys on the keyboard) with a specifiable call condition which will be compared to the actual condition of the key (using GLFW), mouse button or cursor every frame to determine whether the callback function should be called.
A condition for a key could be KeyCondition(PRESS, LEFT_SHIFT) which would call the callback bound to the key if the key was pressed while left shift is being held down.
My problem is that I can only assign these buttons functions of the type void(*)(), which disables me to pass arguments to a button callback.
If for example I wanted to make a button light up when the cursor hovers over it, I would have to create a designated function void highlightButtonA() which sets the color of button A to a higher value internally, while I would of course much rather be able to set the callback to something like void offsetColor(unsigned int buttonIndex, float r, float g, float b, float a) and pass individual parameters to each callback.
Is there any way to do this? Is there some function pointer which can point to a function of any shape and will store parameters somehow? How much should I worry about the performance of these solutions? My program has to be able to handle multiple key/button presses per second and still be stable, as it is a fast-paced shooter game.
You can use non-capturing lambdas that decay to function pointers, something like this:
button.OnMouseHover([]{ offsetColour(buttonIndex, r, g, b, a); });
just remember that buttonIndex and other args to offsetColour should be literals as the lambda cannot capture variables from the enclosing scope.
In my scene I have a vector with multiple custom sprites. When I tap on one of them, I want an action to be fired on another element on the scene, can be another sprite in the vector, or another node. I have been researching the best way to do this, but I'm not quite sure how to implement it. The options are:
Add a touch listener to the scene, and verify if it was tapped inside the bounds of the sprite with rect. containsPoint(point). And after that, I have to get the sprite that was tapped to do the action I want. For me, it doesn't seems very clean to do it this way. And if two sprites are overlaped, I have to verify if the sprite is behind or in the front in order to retrieve the desired sprite. I followed this example: Touch Event example
Add a touch listener in the subclass of the sprite (my custom sprite). And add onTouchBegan and onTouchEnded inside it. But this way, I don't know how to modify an attribute of another sprite, or another element in the scene (Is it possible to use Delegates like Objective-C does?). I followed this example: Subclass Sprite Example
My main problem is that I don't understand very well how to make a node interact with another node in the scene. I have seen a lot of tutorials, but in all of them, when you interact with a node, it only changes its attributes, not other nodes' attributes.
Thanks in advance.
I shall propose "EventCustom" way :)
You can add in your touchBegan / touchEnded methods (wherever you put them... you got the point...) additional code for passing an EventCusto to the _eventDispatcher and get it announced to the world ;)
EventCustom *e = new EventCustom("MyAwesomeEvent");
e->setUserData(ptrMyFantasticData); //This function takes a void pointer. cheers :)
_eventDispatcher->dispatchEvent(e);
You may subclass the EventCustom class but that is hardly necessary. You can always hang an object to it with setUserData().
Now the objects which need to react to the event can listen to it by
_myCustomListener = EventListenerCustom::create(
"MyAwesomeEvent",
CC_CALLBACK_1(
ListeningClass::onMyAwesomeEvent,
this
)
);
_eventDispatcher->addEventListenerWithXXXXXPriority(_myCustomListener, XXX);
//ScreenGraphPriority / FixedPriority depends on situation. Either should work.
It's always a good practice to remove your listeners when you go off, so somewhere, perhaps in onExit(), where you removed touch listeners remove this listener too, as
_eventDispatcher->removeEventListener(_myCustomListener);
Going a bit off the track, a clarification:
CC_CALLBACK_X are a bit tricky names. The X indicates the no. of args the target function will get. Here, event dispatcher will pass 1 arg i.e. ptr to object of EventCustom you handed it, so we use CC_CALLBACK_1. The next arg - here "this" - is the object on which the method will be invoked.
In short, we may say that this callback is going to result into a function call this->onMyAwesomeEvent(e);
For CC_CALLBACK_2 onwards, we can specify additional args, 3rd arg onwards.
Coming back to the issue at hand, ListeningClass::onMyAwesomeEvent will look something like
void ListeningClass::onMyAwesomeEvent(EventCustom *e)
{
MyFantasticData *d = (MyFantasticData *) e->getUserData();
CCLOG("[ListeningClass::onMyAwesomeEvent] %d", d->getMyPreciousInt());
}
Hope it helps :)
Set your elements tags or names with setTag and setName. Then if element x is touched, get them with getChildByTag or getChildByName and do what you need to do.
With the second option you list above.
To make a node interact with another node in the scene you can add touch callback function to your custom sprite object like that:
https://github.com/Longpc/RTS/tree/master/Classes/base/dialogBase
and in main scene you can define function to handle this callback. So you can do every thing to unit in you scene
This may seem like a trivial question, or I may have misunderstood previous information/the research I've done so far.
But is it possible to have a object with a function (in C++) that can access all instances of its own type?
In the context of my usage. I wanted to have a Button class, whereby I could simply instantiate multiple Buttons but call to a function could call reference all buttons.
ButtonInstance.isMouseTargetting(cursorCoordinates);
Is this possible? If so is it efficient?
Or should I have the class which owns the Button instances call each instance to check if the mouse coordinates match up?
I'm under the impression you are looking for advice on how to design this.
In the context of my usage. I wanted to have a Button class, whereby I
could simply instantiate multiple Buttons but call to a function could
call reference all buttons.
You want to do this in a button container. A button is not a button container and in a GUI context you already have an established hirerarchy.
Or should I have the class which owns the Button instances call each
instance to check if the mouse coordinates match up?
Yes. You probably already have a window/container class for this.
Your question is more of about Design pattern than C++ itself. Take a look at the Gang of Four book;you will find an appropriate implementation.
You can, for example, make a list of all objects created for a given class,
class Button {
public:
Button() {
_buttonList.push_back( this );
// assign index/handler to this button
}
~Button() {
_buttonList.erase( _handle );
}
static bool isMouseTargeting( float x, float y ) {
for ( auto button : _buttonList ) {
// check if inside
}
return false;
}
private:
static std::list< Button* > _buttonList;
// Handler _handle;
}
This is only a very general example of what you could do. You can use any other container besides a list (entirely up to you), and you have to find a way to index each button (or create a handle) so that you can later erase it in the destructor.
Beware of the default constructors (copy or move). If you don't explicitly create your constructors then some of your buttons will not enter the list, so either make them yourself or delete them.
Button( const Button& button ) = delete;
This is one way to do what you asked, but not necessarily the best solution. It may be simpler to just add the buttons to a non-static container by yourself and search from there.
The short answer is yes. But i will not recommend to put this functionality on the Button class since this will add extra (maybe not expected) responsibility to it. You can achieve the desired behavior by storing your Button objects on some collection and then call a function to check which button is targeted by the mouse.
Another solution would be to store the buttons collection as a member of a higher level class that represents your user-interface. This way you can call a method of this class and check if the mouse cursor is currently on some Button or not. With this design you can add the same support for other GUI elements (if you need to) easily.
Say I have two main classes, Application and ApplicationGUI. Application does lots of things and can happily run without any knowledge that ApplicationGUI exists. ApplicationGUI is linked to Application in many ways, it has maybe 50 or 100 different knobs that can change Application's behavior.
ApplicationGUI is a hierarchical structure such that it has many instances of ControlGroup, each containing an arbitrary number of Buttons and Knobs, or even another ControlGroup.
Current design: Upon instantiation of the ApplicationGUI (Application was already running with some set of default parameters), I pass pointers of Application's parameters to various components of the GUI. For example:
my_gui.sound_controlgroup.knob.link_to_param(&(my_application.volume));
If I need to do something more complex, say call a member function of Application, my_application.update_something(), how is this done?
The easy answer is to pass a pointer to my_application to my_gui.sound_controlgroup.knob, but if I only ever need to call one of my_application's functions, it seems like I am giving my knob an option to change all kinds of things that it should even know about (my_application.update_something_unrelated(), for instance). What is the cleanest thing to do in this case?
Additionally, this either requires making all subcomponents of ApplicationGUI public or having a function at each stage of the hierarchy to forward that pointer to the bottom level. This leads to quite a lot of functions. Is this a necessary consequence of a UI with a lot of knobs?
Quick Short Answer
In order to implement interaction between your non GUI related Application object and your GUIApplication object I suggest apply the "Property and Method and Event Handler" paradigm.
Extended Complex Answer
G.U.I. development is one of the most practical implementation of the O.O.P. theory.
What is the "Property and Method and Event Handler" paradigm ?
That means build, both Non GUI Classes, and GUI Classes, should have:
Properties
Methods
Event handlers
"Events" (Handlers) are also called "Signals", and are implemented with functions pointers. Not sure, but, I think your "knob" (s) are like Event Handlers.
It's a technique to apply the my_application.update_something_unrelated(), you have in your question.
Since, C++, like Java, does not have property syntax, you may use "getter" and "setter" methods, or use a "property" template.
For example, if your application has a Close method, you may declare something like the following examples.
Note: They are not full programs, just an idea:
// Applications.hpp
public class BaseApplicationClass
{
// ...
};
public class BaseApplicationClientClass
{
// ...
};
typedef
void (BaseApplicationClientClass::*CloseFunctor)
(BaseApplicationClass App);
public class ApplicationClass: public BaseApplicationClass
{
// ...
public:
Vector<BaseApplicationClientClass::CloseFunctor>
BeforeCloseEventHandlers;
Vector<BaseApplicationClientClass::CloseFunctor>
AfterCloseEventHandlers;
protected:
void ConfirmedClose();
public:
virtual void Close();
} Application;
// Applications.cpp
void ApplicationClass::ConfirmedClose()
{
// do close app. without releasing from memory yet.
} // void ApplicationClass::ConfirmedClose()
void ApplicationClass::Close()
{
// Execute all handlers in "BeforeCloseEventaHandlers"
this.ConfirmedClose();
// Execute all handlers in "AfterCloseEventaHandlers"
} // void ApplicationClass::Close()
// AppShells.cpp
public class AppShell: public BaseApplicationClientClass
{
// ...
};
void AppShell::CloseHandler(ApplicationClass App)
{
// close GUI
} // void AppShell.CloseHandler(ApplicationClass App)
void AppShell::setApp(ApplicationClass App)
{
App->BeforeCloseEventHandlers->add(&this.CloseHandler);
} // void AppShell.setApp(ApplicationClass App)
void main (...)
{
ApplicationClass* AppKernel = new ApplicationClass();
ApplicationGUIClass* AppShell = new ApplicationGUIClass();
AppShell.setApp(App);
// this executes "App->Run();"
AppShell->Run();
free AppShell();
free AppKernel();
}
UPDATE: Fixed type declaration from global function pointer (a.k.a. "global functor") to object function pointer (a.k.a. "method functor").
Cheers.
Do you know about the model-view-controller (MVC) paradigm? Think of the Application class as the model, the entire hierarchy of GUI controls as the view, and the ApplicationGUI class as the controller. You don't want Application to know about the controls, and you don't want the controls to know about Application; they should both talk only to the controller, ApplicationGUI.
Using ApplicationGUI as the conduit for communication between controls and Application means that you can test either Application or controls by replacing the other with a mock object, for example. More importantly, you can change either the controls or Application without impacting the other. Individual controls don't need to know anything about Application -- they only need to know where to send their value when it changes. And Application shouldn't care whether an input comes from a knob or a slider or a text field. Keeping those two areas separate will simplify each of them.
Additionally, this either requires making all subcomponents of
ApplicationGUI public or having a function at each stage of the
hierarchy to forward that pointer to the bottom level. This leads to
quite a lot of functions. Is this a necessary consequence of a UI with
a lot of knobs?
A given control shouldn't care what value it manages. It doesn't need to know whether the value determines the number of alien invaders on the screen or the coolant level in a nuclear reactor. It does needs to know things like the minimum and maximum values, label to display, scale to use (linear, log, etc.), and other things that directly impact the way the control works. It also needs to know who to tell when something changes, and it might need some way to identify itself.
With that in mind, ApplicationGUI doesn't need to expose accessors for every possible parameter of Application. Instead, it should have a general method that lets controls send it updates. When a control changes, it should send a message to ApplicationGUI containing the new value(s) along with its identifier, and ApplicationGUI takes care of mapping that identifier to some particular parameter of Application. A control's identifier could be some identifying number that's given to it, or it could just be a pointer to the control.
Of course, sometimes communication has to go the other way, too... a GUI usually has both inputs and outputs, so you'll want some means for ApplicationGUI to get updates from Application and update the state of the GUI. For the same reasons described above, Application should send those updates to ApplicationGUI and let the latter find the actual UI components that need to be changed.
Warning this is a long question!
I am implementing a Solitaire card game in C++ on Win32, and after asking this question, it's becoming clear that I may need a bit of guidance regarding actual class design rather than implementation details.
I am using a model view Controller pattern to implement the game. The model is the game, cards, columns and move history. The view is responsible for painting to screen and the control responsible for handling messages and the timer.
The aspect of the game that I am currently trying to implement is the Action history, which belongs to the Model - I want to be able to "undo" and "redo" any Action.
I describe a Move object as an atomic move of a single card from one CardPile to another. And I described an Action as consisting of one or more Moves. e.g. a deal will be 10 Moves from the Deck to a particular Column. ( Deck and Column are simply specializations of CardPile).
I define the Action as a deque of Moves, and have provided some functions to GetCurrentMove() and to Advance() a move when it has been performed.
class Action
{
public:
void SetMoves( std::deque<Move> dmoves){ _m_deque = dmoves; }
void Advance();
std::deque<Move>::const_iterator GetCurrentMove();
private:
std::deque<Move> _m_deque;
std::deque<Move>::const_iterator currentmove;
};
When dealing (or setting up, or undoing), these Move objects are data for an animation. I need to be able to access a single Move object at a time. I retrieve the Move, parse it into x,y co-ords and then kick off an animation to move a card from one place to another on screen. When the card has reached its destination, I then pull another Move from the deque.
I have been advised by others with more experience, not to store iterators inside the Action class. The STL doesn't do this and there are good reasons apparently.
But my question is - don't I have to store iterators inside the Action class?
You see both my Model and View need access to the current Move, so where else can I store that iterator that refers to the current Move ... inside the Controller?
My game animation is based (very broadly) on this model:
void control.game_loop( message )
{
switch( message )
{
case TIMER:
{
if( view.CardHasReachedDestination() )
{
game.AdvanceAnimation();
if( !game.AnimationFinished() )
view.Parse(game.GetNextMove());
}
view.MoveCardXY();
view.PaintToTheScreen();
controller.StartTheTimerAgain();
}
}
}
Best wishes,
BeeBand
I would create a function template to animate an entire Action, not just one Move at a time. Invoke that with beginning and ending iterators for the Action that needs to be animated:
template <class iterator>
void animate_action(iterator first, iterator last) {
for (iterator i=first; i!=last; ++i)
animate_move(*i);
}
Where animate_move is pretty much what you already had for showing the animation of a single move. You'd invoke this with something like:
animate_action(action.begin(), action.end());
or to animate in reverse order:
animate_action(action.rbegin(), action.rend());
This is (a large part of) why you want to make animate_action a template -- this way it neither knows nor cares whether it receives a forward iterator or a reverse_iterator.
Edit: Based on the further comments, there seem to be a few alternatives.
The standard stand-by would be to use a separate thread to handle the animated drawing, so it would just have something like:
while (current_position != final_position) {
draw_card(currrent_position);
current_position = next_position();
sleep(timer_period);
}
Another would be rather than waiting for a timer to fire, and requesting the current iterator at that point, I'd tend to create and queue up an object representing each move in the animation, then when the timer fires, the timer function retrieves and executes the next item in the queue:
for (int i=0;i<Move.size(); i++)
for (int j=0; j<num_positions; j++)
enqueue(move, Move[i], position(j));
If you use a list instead of a deque, then the iterators pointing to an element will remain valid for the lifetime of the element.
If you do that, I don't see anything wrong with storing iterators in this case.