📄 z_listen.cpp
字号:
// Zinc Application Framework - Z_LISTEN.CPP// Copyright (c) 1990-1998 Zinc Software, Inc.// Copyright (c) 1999-2003 Wind River Systems, Inc./*modification history--------------------01u,19jun03,jlb Fix SPR 72839 - Support SH770001t,19jul01,wdf Fixed compile problem with new StrongArm compiler.01s,17jul01,wdf Fixed compile problem with new MIPS compiler (T2.1).01r,07may01,wdf Changed copyright date.01q,23oct00,wdf Changed copyright date.01p,26sep00,bbj Fixes for SH01o,19sep00,bbj Fix compile problems for SH01n,20apr00,wdf Added DecrementUseCount() to DestroyList.01m,30mar00,jom Add explicit instantiation of templates for GNU and vxWorks01l,30mar00,wdf Fixed various problems.01k,27mar00,wdf Added functionality to ZafListenerHookBase and ZafCListener.01j,22mar00,jom Fix templates for older compilers01i,17mar00,jom Added copy ctor and Duplicate function01h,17mar00,wdf Added typedefs and a template instantation so the inline could be removed from ZafFind.01g,15mar00,jom Changed ZafListenerStack to use ZafVector01f,15mar00,jom Fix ZafAutoListener dtor01e,14mar00,wdf Modified AddListener() to take a 3rd parameter.01d,13mar00,wdf Modified code to use the ZafVector class.01c,28feb00,wdf Added ZafListenerStack class.01b,28feb00,jom Optimize for empty ZafListeners01a,25feb00,wdf Added ZafAutoListener.*/#include <zinc/z_sysevt.hpp>#include <zinc/z_objid.hpp>#include <zinc/z_win.hpp>// Explicitly instantiate the templates for the GNU compiler#if !defined(ZAF_MSWINDOWS)template class ZafVector<ZafListenerHookBase *>;template class ZafVector<ZafEventType>;#endif// ----- ZafAutoListener ----------------------------------------------------ZafAutoListener::ZafAutoListener(ZafWindowObject *object, const ZafEventStruct &listenerEvent, ZafEventType &listenerCcode) : windowObject(object), event((ZafEventStruct &)listenerEvent), ccode(listenerCcode){ // Optimize for empty listener lists if (windowObject->preListener.Empty() && windowObject->postListener.Empty()) return; if (windowObject->listenerStack.Empty()) windowObject->listenerStack.Push(ccode); else { ZafListenerStackStruct &listenerStruct = windowObject->listenerStack.Peek(); if (listenerStruct.ccode == ccode) ++listenerStruct.stackCount; else windowObject->listenerStack.Push(ccode); } // If at the most derived class call the event listener. if (windowObject->listenerStack.Peek().stackCount == 1) { windowObject->preListener.Process(windowObject, event, ccode); }}ZafAutoListener::~ZafAutoListener(){ // Optimize for empty listener lists if (windowObject->listenerStack.Empty()) return; ZafListenerStackStruct &listenerStruct = windowObject->listenerStack.Peek(); // If at the most derived class level and the event has not been processed, // call the event listener. if (listenerStruct.stackCount == 1 && !event.processed) { windowObject->postListener.Process(windowObject, event, ccode); } if (--listenerStruct.stackCount == 0) windowObject->listenerStack.Pop();}// ----- ZafListenerHookbase ------------------------------------------------struct FindEventStruct{ FindEventStruct(ZafEventType _ccode, ZafEventType _ocode) : ccode(_ccode), ocode(_ocode) {} bool operator () (ZafEventType compare) const { return (compare == ccode || compare == ocode); } ZafEventType ccode; ZafEventType ocode;};// Explicitly instantiate the templates for the GNU compiler#if !defined(ZAF_MSWINDOWS)typedef ZafListenerHookBase::DeviceTypeVector::const_iterator cDeviceIter;typedef ZafListenerHookBase::DeviceTypeVector::iterator deviceIter;template cDeviceIter ZafFindIf(cDeviceIter, cDeviceIter, FindEventStruct);template deviceIter ZafFind(deviceIter, deviceIter, const ZafDeviceType &);#if (CPU != SH7750 && CPU != MIPS32 && CPU != MIPS64 && CPU != STRONGARM)typedef ZafListenerHookBase::EventTypeVector::iterator eventIter;#endif#endifZafListenerHookBase::ZafListenerHookBase() : count(0){}ZafListenerHookBase::~ZafListenerHookBase(){}void ZafListenerHookBase::AddEvent(ZafEventType ccode){ EventTypeVector::iterator iter; // If the event has already been added return. iter = ZafFind(events.Begin(), events.End(), ccode); if (iter != events.End()) return; events.AddElement(ccode);}void ZafListenerHookBase::AddInputType(ZafDeviceType inputType){ DeviceTypeVector::iterator iter; // If the inputType has already been added return. iter = ZafFind(devices.Begin(), devices.End(), inputType); if (iter != devices.End()) return; devices.AddElement(inputType);}void ZafListenerHookBase::RemoveEvent(ZafEventType ccode){ EventTypeVector::iterator iter; // If the event is found remove it. iter = ZafFind(events.Begin(), events.End(), ccode); if (iter != events.End()) events.RemoveElement(iter);}void ZafListenerHookBase::RemoveInputType(ZafDeviceType inputType){ DeviceTypeVector::iterator iter; // If the inputType has already been added return. iter = ZafFind(devices.Begin(), devices.End(), inputType); if (iter != devices.End()) devices.RemoveElement(iter);}bool ZafListenerHookBase::Handles(ZafEventType ccode, ZafEventType inputType) const{ // Check for a valid inputType. DeviceTypeVector::const_iterator iter; iter = ZafFindIf(devices.Begin(), devices.End(), FindEventStruct(inputType, E_DEVICE)); if(iter != devices.End()) { // If valid inputType check for a valid ccode. EventTypeVector::const_iterator iter; iter = ZafFindIf(events.Begin(), events.End(), FindEventStruct(ccode, S_ANY)); if (iter != events.End()) return(true); } // Event is not a valid event. return(false);}int ZafListenerHookBase::DecrementUseCount(){ return(--count);}int ZafListenerHookBase::IncrementUseCount(){ return(++count);}bool ZafListenerHookBase::IsA(ZafClassID ){ return(false); // Default behavior is to return false}int ZafListenerHookBase::UseCount() const{ return(count);}// ----- ZafCListener -------------------------------------------------------ZafCListener::ZafCListener(ZafCallback tCallback) : callback(tCallback){}ZafCListener::ZafCListener(ZafCallback tCallback, ZafEventType ccode, ZafEventType inputType) : callback(tCallback){ AddEvent(ccode); AddInputType(inputType);}ZafListenerHookBase *ZafCListener::Construct(ZafCallback tCallback, ZafEventType ccode, ZafDeviceType inputType){ return(new ZafCListener(tCallback, ccode, inputType));} ZafListenerHookBase *ZafCListener::Construct(ZafCallback tCallback, ZafEventType *ccode, ZafDeviceType *inputType){ ZafCListener *listener = new ZafCListener(tCallback); int i; for (i = 0; ccode && ccode[i] != 0; i++) listener->AddEvent(ccode[i]); for (i = 0; inputType && inputType[i] !=0; i++) listener->AddInputType(inputType[i]); return(listener);}ZafEventType ZafCListener::Process(ZafWindowObject *object, ZafEventStruct &event, ZafEventType ccode){ return((*callback)(object, event, ccode));}bool ZafCListener::IsA(ZafClassID tClassID){ return (tClassID == classID);}bool ZafCListener::operator==(const ZafCListener &listener) const{ return (callback == listener.callback);}ZafListenerHookBase *ZafCListener::Duplicate() const{ return(new ZafCListener(*this));}ZafCListener::ZafCListener(const ZafCListener &other): ZafListenerHookBase(other), callback(other.callback){}const ZafClassID ZafCListener::classID = ID_ZAF_C_LISTENER;// ----- ZafListener --------------------------------------------------------ZafListener::ZafListener(){}ZafListener::~ZafListener(){ DestroyList();}ZafListener::ZafListener(const ZafListener ©){ const_iterator start = copy.Begin(); const_iterator finish = copy.End(); for (; start != finish; ++start) AddListener((*start)->Duplicate());}ZafEventType ZafListener::Process(ZafWindowObject *object, ZafEventStruct &event, ZafEventType ccode){ ZafEventType rVal = ccode; ZafEventType inputType = event.InputType(); for (iterator iter= Begin(); iter != End() && !event.processed; ++iter) { if ((*iter)->Handles(ccode, inputType)) rVal = (*iter)->Process(object, event, ccode); } return (rVal);}typedef ZafListener::iterator ListenIter;typedef ZafListenerHookBase* PHook;template ListenIter ZafFind(ListenIter, ListenIter, const PHook&);void ZafListener::AddListener(ZafListenerHookBase *object, bool addToEnd){ if (object && listenerVector.End() == ZafFind(listenerVector.Begin(), listenerVector.End(), object)) { listenerVector.InsertElement(object, addToEnd ? listenerVector.End() : listenerVector.Begin()); object->IncrementUseCount(); }}bool ZafListener::RemoveListener(ZafListenerHookBase *object){ iterator iter = ZafFind(listenerVector.Begin(), listenerVector.End(), object); if (iter != listenerVector.End()) { object->DecrementUseCount(); listenerVector.RemoveElement(iter); return(true); } return (false);}ZafListener::const_iterator ZafListener::Begin(void) const{ return (listenerVector.Begin());}ZafListener::const_iterator ZafListener::End(void) const{ return (listenerVector.End());}ZafListener::iterator ZafListener::Begin(void){ return (listenerVector.Begin());}ZafListener::iterator ZafListener::End(void){ return (listenerVector.End());}void ZafListener::DestroyList(){ // Free any "owned" listeners. iterator iter = Begin(); iterator endIter = End(); for (; iter != endIter; ++iter) { (*iter)->DecrementUseCount(); if ((*iter)->UseCount() == 0) delete (*iter); }}bool ZafListener::Empty(void){ return (listenerVector.Empty());}// ----- ZafListenerStack --------------------------------------------------------#if !defined(ZAF_MSWINDOWS)template class ZafVector<ZafListenerStackStruct>;#endifZafListenerStack::ZafListenerStack(){}bool ZafListenerStack::Empty(){ return (vector.Empty());}ZafListenerStackStruct &ZafListenerStack::Peek(){ return (*(vector.End() - 1));}void ZafListenerStack::Pop(){ if (!vector.Empty()) vector.RemoveElement(vector.End() - 1);}void ZafListenerStack::Push(ZafEventType ccode){ ZafListenerStackStruct tStruct; tStruct.ccode = ccode; tStruct.stackCount = 1; vector.AddElement(tStruct);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -