Показать сообщение отдельно
Старый 29.05.2015, 18:57   #887
mr.DIMAS
Дэвелопер
 
Аватар для mr.DIMAS
 
Регистрация: 26.12.2006
Адрес: Санкт-Петербург
Сообщений: 1,572
Написано 547 полезных сообщений
(для 1,540 пользователей)
Ответ: [TrueHorror] - разработка

Появилось еще немного времени на игрушку. Недавно скачал юнити 5, поковырял новый гуй, и понял что хочу такой же. Действия кнопочек\слайдеров\радиокнопок выполняются через делегаты, но в цпп нет делегатов. Пришлось запилить.

class ruIContainer {
public:
    virtual ~ruIContainer() {    

    };

    virtual void Call() = 0;
};

template< class T, class M > class ruContainer : public ruIContainer {
private:
    T * mClass;
    M mMethod;
public:
    explicit ruContainer( T * theClass, M  theMethod ) : mClass( theClass ), mMethod( theMethod ) {

    };

    virtual void Call() {
        (mClass->*mMethod)();
    }
};

class ruDelegate {
private:
    ruIContainer * mContainer;
public:
    ruDelegate() : mContainer( nullptr ) {

    };
    ~ruDelegate() {
        if( mContainer ) {
            delete mContainer;
        }
    }
    ruDelegate( const ruDelegate & other ) {
        mContainer = other.mContainer;
        (const_cast<ruDelegate&>(other)).mContainer = nullptr;
    }
    template< class T, class M > static ruDelegate Bind( T * theClass, M  theMethod ) {
        ruDelegate delegat;
        delegat.mContainer = new ruContainer< T, M >( theClass, theMethod );
        return delegat;
    }
    void Call() {
        if( mContainer ) {
            mContainer->Call();
        }
    }
    void operator = ( const ruDelegate & other ) {
        mContainer = other.mContainer;
        (const_cast<ruDelegate&>(other)).mContainer = nullptr;
    }
};

class ruEvent {
private:
    vector<ruDelegate> mListenerList;
public:
    void AddListener( const ruDelegate & delegat ) {
        mListenerList.push_back( delegat );
    }

    void RemoveAllListeners() {
        mListenerList.clear();
    }

    void DoActions() {
        for( auto iter = mListenerList.begin(); iter != mListenerList.end(); iter++ ) {
            iter->Call();
        }
    }
};
Пользуюсь так
... где-то внутри класса Menu
button.AddListener( ruDelegate::Bind( this, &Menu::OnButtonClick ));
Плюсы делегатов для гуя можно перечислять долго, но от себя скажу, что с ними я запилил модальные окна для вопросов, анимацию элементов меню и много еще чего. И все очень удобно, не нужно городить неведомый спагетти-код.

Немного скриншотов, графон в гуй не завезли - и скрины заболели джпегом. Кстати последние скрины с исправленным хдр и без него.
Миниатюры
Нажмите на изображение для увеличения
Название: TheMine 2015-05-29 17-58-08-70.jpg
Просмотров: 890
Размер:	66.3 Кб
ID:	21745  Нажмите на изображение для увеличения
Название: TheMine 2015-05-29 17-58-21-39.jpg
Просмотров: 923
Размер:	68.7 Кб
ID:	21746  Нажмите на изображение для увеличения
Название: TheMine 2015-05-29 17-58-28-48.jpg
Просмотров: 914
Размер:	69.7 Кб
ID:	21747  Нажмите на изображение для увеличения
Название: TheMine 2015-05-29 17-58-35-43.jpg
Просмотров: 897
Размер:	70.2 Кб
ID:	21748  Нажмите на изображение для увеличения
Название: TheMine 2015-05-29 17-59-49-82.jpg
Просмотров: 995
Размер:	66.3 Кб
ID:	21749  

Нажмите на изображение для увеличения
Название: TheMine 2015-05-29 17-59-51-50.jpg
Просмотров: 932
Размер:	87.0 Кб
ID:	21750  Нажмите на изображение для увеличения
Название: TheMine 2015-05-29 18-02-00-10.jpg
Просмотров: 887
Размер:	121.5 Кб
ID:	21751  Нажмите на изображение для увеличения
Название: TheMine 2015-05-29 18-02-17-97.jpg
Просмотров: 937
Размер:	121.1 Кб
ID:	21752  
__________________

(Offline)
 
Ответить с цитированием
Эти 2 пользователя(ей) сказали Спасибо mr.DIMAS за это полезное сообщение:
FREE MAN (29.05.2015), Samodelkin (29.05.2015)