genesis-3d_engine/Engine/foundation/delegates/delegate_implement.h

429 lines
12 KiB
C
Raw Permalink Normal View History

/*!
@file
@author Albert Semenov
@date 11/2007
*/
/*
This file is part of MyGUI.
MyGUI is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
MyGUI is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with MyGUI. If not, see <http://www.gnu.org/licenses/>.
*/
//Copy from mygui.
namespace delegates
{
#ifndef GENESIS_OBSOLETE //mygui<75><69><EFBFBD>ĵ<EFBFBD><C4B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ص<EFBFBD><D8B5><EFBFBD>Ϣ<EFBFBD><CFA2><EFBFBD><EFBFBD>û<EFBFBD><C3BB><EFBFBD><EFBFBD><EFBFBD>õ<EFBFBD><C3B5>Բ<EFBFBD><D4B2>֣<EFBFBD><D6A3><EFBFBD><EFBFBD><EFBFBD>Ҫ<EFBFBD><D2AA><EFBFBD>Ե<EFBFBD>
#define GENESIS_OBSOLETE(text)
#endif
#ifndef GENESIS_EXCEPT //mygui<75><69><EFBFBD>ĵ<EFBFBD><C4B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ص<EFBFBD><D8B5><EFBFBD>Ϣ<EFBFBD><CFA2><EFBFBD><EFBFBD>û<EFBFBD><C3BB><EFBFBD><EFBFBD><EFBFBD>õ<EFBFBD><C3B5>Բ<EFBFBD><D4B2>֣<EFBFBD><D6A3><EFBFBD><EFBFBD><EFBFBD>Ҫ<EFBFBD><D2AA><EFBFBD>Ե<EFBFBD>
#define GENESIS_EXCEPT(dest) //n_error(dest);
#endif
#define GENESIS_COMBINE(a, b) GENESIS_COMBINE1(a, b)
#define GENESIS_COMBINE1(a, b) a##b
#define MYGUI_I_DELEGATE GENESIS_COMBINE(IDelegate, GENESIS_SUFFIX)
#define MYGUI_C_STATIC_DELEGATE GENESIS_COMBINE(CStaticDelegate, GENESIS_SUFFIX)
#define MYGUI_C_METHOD_DELEGATE GENESIS_COMBINE(CMethodDelegate, GENESIS_SUFFIX)
#define MYGUI_C_DELEGATE GENESIS_COMBINE(CDelegate, GENESIS_SUFFIX)
#define MYGUI_C_MULTI_DELEGATE GENESIS_COMBINE(CMultiDelegate, GENESIS_SUFFIX)
#ifndef nullptr
#define nullptr 0
#endif
// <20>ҧѧ٧<D1A7><D9A7>ӧ<EFBFBD><D3A7><EFBFBD> <20>ܧݧѧ<DDA7><D1A7><EFBFBD> <20>ӧ<EFBFBD><D3A7>֧<EFBFBD> <20>է֧ݧ֧ԧѧ<D4A7><D1A7><EFBFBD><EFBFBD><EFBFBD>
GENESIS_TEMPLATE GENESIS_TEMPLATE_PARAMS
class MYGUI_I_DELEGATE
{
public:
virtual ~MYGUI_I_DELEGATE() { }
#ifndef DELEGATE_RTTI_DISABLE_TYPE_INFO
virtual bool isType( const std::type_info& _type) = 0;
#endif
virtual void invoke( GENESIS_PARAMS ) = 0;
virtual bool compare( MYGUI_I_DELEGATE GENESIS_TEMPLATE_ARGS* _delegate) const = 0;
virtual bool compare(IDelegateUnlink* _unlink) const
{
return false;
}
};
// <20>է֧ݧ֧ԧѧ<D4A7> <20>էݧ<D5A7> <20><><EFBFBD><EFBFBD><EFBFBD>ѧ<EFBFBD><D1A7>ڧ<EFBFBD><DAA7>֧<EFBFBD><D6A7>ܧ<EFBFBD><DCA7><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ߧܧ<DFA7><DCA7>ڧ<EFBFBD>
GENESIS_TEMPLATE GENESIS_TEMPLATE_PARAMS
class MYGUI_C_STATIC_DELEGATE : public MYGUI_I_DELEGATE GENESIS_TEMPLATE_ARGS
{
public:
typedef void (*Func)( GENESIS_PARAMS );
MYGUI_C_STATIC_DELEGATE (Func _func) : mFunc(_func) { }
#ifndef DELEGATE_RTTI_DISABLE_TYPE_INFO
virtual bool isType( const std::type_info& _type)
{
return typeid( MYGUI_C_STATIC_DELEGATE GENESIS_TEMPLATE_ARGS ) == _type;
}
#endif
virtual void invoke( GENESIS_PARAMS )
{
mFunc( GENESIS_ARGS );
}
virtual bool compare( MYGUI_I_DELEGATE GENESIS_TEMPLATE_ARGS* _delegate) const
{
#ifndef DELEGATE_RTTI_DISABLE_TYPE_INFO
if (nullptr == _delegate || !_delegate->isType(typeid(MYGUI_C_STATIC_DELEGATE GENESIS_TEMPLATE_ARGS)) ) return false;
MYGUI_C_STATIC_DELEGATE GENESIS_TEMPLATE_ARGS* cast = static_cast<MYGUI_C_STATIC_DELEGATE GENESIS_TEMPLATE_ARGS*>(_delegate);
#else
MYGUI_C_STATIC_DELEGATE GENESIS_TEMPLATE_ARGS* cast = dynamic_cast<MYGUI_C_STATIC_DELEGATE GENESIS_TEMPLATE_ARGS*>(_delegate);
if (nullptr == cast) return false;
#endif
return cast->mFunc == mFunc;
}
virtual bool compare(IDelegateUnlink* _unlink) const
{
return false;
}
private:
Func mFunc;
};
// <20>է֧ݧ֧ԧѧ<D4A7> <20>էݧ<D5A7> <20>ާ֧<DEA7><D6A7><EFBFBD><EFBFBD>է<EFBFBD> <20>ܧݧѧ<DDA7><D1A7><EFBFBD><EFBFBD><EFBFBD>
template GENESIS_T_TEMPLATE_PARAMS
class MYGUI_C_METHOD_DELEGATE : public MYGUI_I_DELEGATE GENESIS_TEMPLATE_ARGS
{
public:
typedef void (T::*Method)( GENESIS_PARAMS );
MYGUI_C_METHOD_DELEGATE(IDelegateUnlink* _unlink, T* _object, Method _method) : mUnlink(_unlink), mObject(_object), mMethod(_method) { }
#ifndef DELEGATE_RTTI_DISABLE_TYPE_INFO
virtual bool isType( const std::type_info& _type)
{
return typeid( MYGUI_C_METHOD_DELEGATE GENESIS_T_TEMPLATE_ARGS ) == _type;
}
#endif
virtual void invoke( GENESIS_PARAMS )
{
(mObject->*mMethod)( GENESIS_ARGS );
}
virtual bool compare( MYGUI_I_DELEGATE GENESIS_TEMPLATE_ARGS* _delegate) const
{
#ifndef DELEGATE_RTTI_DISABLE_TYPE_INFO
if (nullptr == _delegate || !_delegate->isType(typeid(MYGUI_C_METHOD_DELEGATE GENESIS_T_TEMPLATE_ARGS)) ) return false;
MYGUI_C_METHOD_DELEGATE GENESIS_T_TEMPLATE_ARGS* cast = static_cast< MYGUI_C_METHOD_DELEGATE GENESIS_T_TEMPLATE_ARGS* >(_delegate);
#else
MYGUI_C_METHOD_DELEGATE GENESIS_T_TEMPLATE_ARGS* cast = dynamic_cast< MYGUI_C_METHOD_DELEGATE GENESIS_T_TEMPLATE_ARGS* >(_delegate);
if (nullptr == cast) return false;
#endif
return cast->mObject == mObject && cast->mMethod == mMethod;
}
virtual bool compare(IDelegateUnlink* _unlink) const
{
return mUnlink == _unlink;
}
private:
IDelegateUnlink* mUnlink;
T* mObject;
Method mMethod;
};
} // namespace delegates
// <20><><EFBFBD>ѧҧݧ<D2A7><DDA7><EFBFBD> <20>էݧ<D5A7> <20><><EFBFBD><EFBFBD><EFBFBD>٧էѧߧڧ<DFA7> <20>է֧ݧ֧ԧѧ<D4A7><D1A7><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ѧ<EFBFBD><D1A7>ڧ<EFBFBD><DAA7>֧<EFBFBD><D6A7>ܧ<EFBFBD><DCA7><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ߧܧ<DFA7><DCA7>ڧ<EFBFBD>
// <20><><EFBFBD>ѧ<EFBFBD><D1A7>ѧާ֧<DEA7><D6A7><EFBFBD><EFBFBD><EFBFBD> : <20><><EFBFBD>ܧѧ٧ѧ<D9A7><D1A7>֧ݧ<D6A7> <20>ߧ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ߧܧ<DFA7><DCA7>ڧ<EFBFBD>
// <20><><EFBFBD><EFBFBD><EFBFBD>ڧާ֧<DEA7> : newDelegate(funk_name);
// <20><><EFBFBD><EFBFBD><EFBFBD>ڧާ֧<DEA7> : newDelegate(class_name::static_method_name);
GENESIS_TEMPLATE GENESIS_TEMPLATE_PARAMS
inline delegates::MYGUI_I_DELEGATE GENESIS_TEMPLATE_ARGS* newDelegate( void (*_func)( GENESIS_PARAMS ) )
{
return new delegates::MYGUI_C_STATIC_DELEGATE GENESIS_TEMPLATE_ARGS (_func);
}
// <20><><EFBFBD>ѧҧݧ<D2A7><DDA7><EFBFBD> <20>էݧ<D5A7> <20><><EFBFBD><EFBFBD><EFBFBD>٧էѧߧڧ<DFA7> <20>է֧ݧ֧ԧѧ<D4A7><D1A7><EFBFBD> <20>ާ֧<DEA7><D6A7><EFBFBD><EFBFBD>է<EFBFBD> <20>ܧݧѧ<DDA7><D1A7><EFBFBD><EFBFBD><EFBFBD>
// <20><><EFBFBD>ѧ<EFBFBD><D1A7>ѧާ֧<DEA7><D6A7><EFBFBD><EFBFBD><EFBFBD> : <20><><EFBFBD>ܧѧ٧ѧ<D9A7><D1A7>֧ݧ<D6A7> <20>ߧ<EFBFBD> <20><><EFBFBD>ҧ<EFBFBD><D2A7>֧ܧ<D6A7> <20>ܧݧѧ<DDA7><D1A7><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD>ܧѧ٧ѧ<D9A7><D1A7>֧ݧ<D6A7> <20>ߧ<EFBFBD> <20>ާ֧<DEA7><D6A7><EFBFBD><EFBFBD><EFBFBD> <20>ܧݧѧ<DDA7><D1A7><EFBFBD><EFBFBD><EFBFBD>
// <20><><EFBFBD><EFBFBD><EFBFBD>ڧާ֧<DEA7> : newDelegate(&object_name, &class_name::method_name);
template GENESIS_T_TEMPLATE_PARAMS
inline delegates::MYGUI_I_DELEGATE GENESIS_TEMPLATE_ARGS* newDelegate( T* _object, void (T::*_method)( GENESIS_PARAMS ) )
{
return new delegates::MYGUI_C_METHOD_DELEGATE GENESIS_T_TEMPLATE_ARGS (delegates::GetDelegateUnlink(_object), _object, _method);
}
namespace delegates
{
// <20><><EFBFBD>ѧҧݧ<D2A7><DDA7><EFBFBD> <20>ܧݧѧ<DDA7><D1A7><EFBFBD><EFBFBD><EFBFBD> <20>է֧ݧ֧ԧѧ<D4A7><D1A7><EFBFBD>
GENESIS_TEMPLATE GENESIS_TEMPLATE_PARAMS
class MYGUI_C_DELEGATE
{
public:
typedef MYGUI_I_DELEGATE GENESIS_TEMPLATE_ARGS IDelegate;
MYGUI_C_DELEGATE () : mDelegate(nullptr) { }
MYGUI_C_DELEGATE (const MYGUI_C_DELEGATE GENESIS_TEMPLATE_ARGS& _event) : mDelegate(nullptr)
{
// <20>٧ѧҧڧ<D2A7><DAA7>ѧ֧<D1A7> <20><><EFBFBD>֧ҧ<D6A7> <20>ӧݧѧէ֧ߧڧ<DFA7>
IDelegate* del = _event.mDelegate;
const_cast< MYGUI_C_DELEGATE GENESIS_TEMPLATE_ARGS& >(_event).mDelegate = nullptr;
if (mDelegate != nullptr && !mDelegate->compare(del))
delete mDelegate;
mDelegate = del;
}
~MYGUI_C_DELEGATE ()
{
clear();
}
bool empty() const
{
return mDelegate == nullptr;
}
void clear()
{
if (mDelegate)
{
delete mDelegate;
mDelegate = nullptr;
}
}
MYGUI_C_DELEGATE GENESIS_TEMPLATE_ARGS& operator=(IDelegate* _delegate)
{
delete mDelegate;
mDelegate = _delegate;
return *this;
}
MYGUI_C_DELEGATE GENESIS_TEMPLATE_ARGS& operator=(const MYGUI_C_DELEGATE GENESIS_TEMPLATE_ARGS& _event)
{
// <20>٧ѧҧڧ<D2A7><DAA7>ѧ֧<D1A7> <20><><EFBFBD>֧ҧ<D6A7> <20>ӧݧѧէ֧ߧڧ<DFA7>
IDelegate* del = _event.mDelegate;
const_cast< MYGUI_C_DELEGATE GENESIS_TEMPLATE_ARGS& >(_event).mDelegate = nullptr;
if (mDelegate != nullptr && !mDelegate->compare(del))
delete mDelegate;
mDelegate = del;
return *this;
}
void operator()( GENESIS_PARAMS )
{
if (mDelegate == nullptr) return;
mDelegate->invoke( GENESIS_ARGS );
}
private:
IDelegate* mDelegate;
};
// <20><><EFBFBD>ѧҧݧ<D2A7><DDA7><EFBFBD> <20>ܧݧѧ<DDA7><D1A7><EFBFBD><EFBFBD><EFBFBD> <20>ާ<EFBFBD><DEA7>ݧ<EFBFBD><DDA7><EFBFBD><EFBFBD><EFBFBD> <20>է֧ݧ֧ԧѧ<D4A7><D1A7><EFBFBD>
GENESIS_TEMPLATE GENESIS_TEMPLATE_PARAMS
class MYGUI_C_MULTI_DELEGATE
{
public:
typedef MYGUI_I_DELEGATE GENESIS_TEMPLATE_ARGS IDelegate;
typedef GENESIS_TYPENAME std::list<IDelegate* /*, Allocator<IDelegate*>*/ > ListDelegate;
typedef GENESIS_TYPENAME ListDelegate::iterator ListDelegateIterator;
typedef GENESIS_TYPENAME ListDelegate::const_iterator ConstListDelegateIterator;
MYGUI_C_MULTI_DELEGATE () { }
~MYGUI_C_MULTI_DELEGATE ()
{
clear();
}
bool empty() const
{
for (ConstListDelegateIterator iter = mListDelegates.begin(); iter != mListDelegates.end(); ++iter)
{
if (*iter) return false;
}
return true;
}
void clear()
{
for (ListDelegateIterator iter = mListDelegates.begin(); iter != mListDelegates.end(); ++iter)
{
if (*iter)
{
delete (*iter);
(*iter) = nullptr;
}
}
}
void clear(IDelegateUnlink* _unlink)
{
for (ListDelegateIterator iter = mListDelegates.begin(); iter != mListDelegates.end(); ++iter)
{
if ((*iter) && (*iter)->compare(_unlink))
{
delete (*iter);
(*iter) = nullptr;
}
}
}
MYGUI_C_MULTI_DELEGATE GENESIS_TEMPLATE_ARGS& operator+=(IDelegate* _delegate)
{
for (ListDelegateIterator iter = mListDelegates.begin(); iter != mListDelegates.end(); ++iter)
{
if ((*iter) && (*iter)->compare(_delegate))
{
GENESIS_EXCEPT("Trying to add same delegate twice.");
}
}
mListDelegates.push_back(_delegate);
return *this;
}
MYGUI_C_MULTI_DELEGATE GENESIS_TEMPLATE_ARGS& operator-=(IDelegate* _delegate)
{
for (ListDelegateIterator iter = mListDelegates.begin(); iter != mListDelegates.end(); ++iter)
{
if ((*iter) && (*iter)->compare(_delegate))
{
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ӧ֧<D3A7><D6A7><EFBFBD><EFBFBD>֧<EFBFBD> <20>ߧ<EFBFBD> <20>ڧէ֧ߧ<D6A7><DFA7>ڧ<EFBFBD><DAA7>ߧ<EFBFBD><DFA7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>է֧ݧ֧ԧѧ<D4A7><D1A7><EFBFBD><EFBFBD><EFBFBD>
if ((*iter) != _delegate) delete (*iter);
(*iter) = nullptr;
break;
}
}
delete _delegate;
return *this;
}
void operator()( GENESIS_PARAMS )
{
ListDelegateIterator iter = mListDelegates.begin();
while (iter != mListDelegates.end())
{
if (nullptr == (*iter))
{
iter = mListDelegates.erase(iter);
}
else
{
(*iter)->invoke( GENESIS_ARGS );
++iter;
}
}
}
MYGUI_C_MULTI_DELEGATE (const MYGUI_C_MULTI_DELEGATE GENESIS_TEMPLATE_ARGS& _event)
{
// <20>٧ѧҧڧ<D2A7><DAA7>ѧ֧<D1A7> <20><><EFBFBD>֧ҧ<D6A7> <20>ӧݧѧէ֧ߧڧ<DFA7>
ListDelegate del = _event.mListDelegates;
const_cast< MYGUI_C_MULTI_DELEGATE GENESIS_TEMPLATE_ARGS& >(_event).mListDelegates.clear();
safe_clear(del);
mListDelegates = del;
}
MYGUI_C_MULTI_DELEGATE GENESIS_TEMPLATE_ARGS& operator=(const MYGUI_C_MULTI_DELEGATE GENESIS_TEMPLATE_ARGS& _event)
{
// <20>٧ѧҧڧ<D2A7><DAA7>ѧ֧<D1A7> <20><><EFBFBD>֧ҧ<D6A7> <20>ӧݧѧէ֧ߧڧ<DFA7>
ListDelegate del = _event.mListDelegates;
const_cast< MYGUI_C_MULTI_DELEGATE GENESIS_TEMPLATE_ARGS& >(_event).mListDelegates.clear();
safe_clear(del);
mListDelegates = del;
return *this;
}
GENESIS_OBSOLETE("use : operator += ")
MYGUI_C_MULTI_DELEGATE GENESIS_TEMPLATE_ARGS& operator=(IDelegate* _delegate)
{
clear();
*this += _delegate;
return *this;
}
private:
void safe_clear(ListDelegate& _delegates)
{
for (ListDelegateIterator iter = mListDelegates.begin(); iter != mListDelegates.end(); ++iter)
{
if (*iter)
{
IDelegate* del = (*iter);
(*iter) = nullptr;
delete_is_not_found(del, _delegates);
}
}
}
void delete_is_not_found(IDelegate* _del, ListDelegate& _delegates)
{
for (ListDelegateIterator iter = _delegates.begin(); iter != _delegates.end(); ++iter)
{
if ((*iter) && (*iter)->compare(_del))
{
return;
}
}
delete _del;
}
private:
ListDelegate mListDelegates;
};
#undef GENESIS_COMBINE
#undef GENESIS_COMBINE1
#undef MYGUI_I_DELEGATE
#undef MYGUI_C_STATIC_DELEGATE
#undef MYGUI_C_METHOD_DELEGATE
#undef MYGUI_C_DELEGATE
#undef MYGUI_C_MULTI_DELEGATE
#undef GENESIS_SUFFIX
#undef GENESIS_TEMPLATE
#undef GENESIS_TEMPLATE_PARAMS
#undef GENESIS_TEMPLATE_ARGS
#undef GENESIS_T_TEMPLATE_PARAMS
#undef GENESIS_T_TEMPLATE_ARGS
#undef GENESIS_PARAMS
#undef GENESIS_ARGS
#undef GENESIS_TYPENAME
} // namespace delegates