2

First I will present some code, then make a description of a problem:

class CGUIObject
{
protected:
    int m_id;
    bool m_bVisible;

    // Other non-relevant fields and methods specific for gui object...
};

class CClickable
{
private:
    bool m_bClicked;
public:
    bool isClicked();
    void setClicked(bool bClicked);

    virtual bool wasClicked(const TPoint& clickPos) = 0;

    // Other non-relevant fields and methods specific for clickable object...
};

class CComponent : public CGUIObject
{
    // The only important part of this class is that it derives from CGUIObject
};    

class CButton : public CComponent, CClickable
{
    // The only important part of this class is that it derives from CComponent and CClickable
};

// Now there is a method in my EventManager which informs all clickables about left mouse click event
void CEventManager::lMouseButtonClickEvent(const CPoint& clickPos)
{
    // Go through all clickables
    for(unsigned int i = 0; i < m_clickableObjectsList.size(); i++)
    {
         TClickable* obj = m_clickableObjectsList[i];

         // Here I would like to also check if obj is visible
         if(obj->wasClicked(clickPos))
         {
          obj->setClicked(true);
          if(obj->m_pOnClickListener != nullptr)
               obj->m_pOnClickListener->onClick();
         return; // Only one object can be clicked at once
         }
    }
}

Ok, so as you can see:

  • CButton derives both from CComponent and CClickable
  • CComponent derives from CGUIObject
  • CGUIObject has m_bVisible field which is important for me
  • In EventManager I have created a list of CClickable* objects

Now I'd like to inform specific CClickable object which was clicked but ONLY if it's visible. I know that all clickables also derive from CGUIObject (e.g. CButton), but it's a list of CClickable* so it's understandable I can't get access to m_bVisible field. I know it simply shows I've made a mistake in designing, but is there way to resolve this problem in some elegant and easy way?

3
  • With a linear complexity, I hope that you have a fairly low number of clickable objects in your application. Commented Nov 29, 2012 at 14:15
  • 1
    @MatthieuM. Sorry, but what do you mean by "linear complexity" in this case? Commented Nov 29, 2012 at 14:17
  • you are iterating through all Clickable objects one at a time to check whether they are visible (and the event should be dispatched to them) or they are not (and nothing has to be done). Therefore, this will take a time at least proportional to the number of Clickable objects, even when only a few are actually of concern. Commented Nov 29, 2012 at 16:22

2 Answers 2

2

If you know all clickables are derived from CGUIObject, you can use a dynamic_cast:

CClickable* obj = m_clickableObjectsList[i];

// Here I would like to also check if obj is visible
if(obj->wasClicked(clickPos) && dynamic_cast<CGUIObject*>(obj)->m_bVisible)
{
  //...

If the clickable was not a GUI object, the dynamic_cast would return a null pointer in such case, and you should check this before dereferencing the result.

Sign up to request clarification or add additional context in comments.

Comments

1

Rather than using something like a dynamic_cast, you have to implement the wasClicked in CButton to say if the button is invisible it was not clicked.

bool CButton::wasClicked() {
    if(!m_bVisible) return false;
    /*previous logic*/
}

1 Comment

Thanks, that really seems to be a better idea

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.