make EventHandler can be owned by caller and loooper

This commit is contained in:
houzh 2024-01-31 17:27:30 +08:00
parent 47cbfa7fdd
commit 1c7cc95046
8 changed files with 54 additions and 28 deletions

View File

@ -75,9 +75,8 @@ void InputEventSource::onDeviceChanged(const INPUTEVENT*es){
}
}
static NeverDestroyed<InputEventSource>mInst;
InputEventSource& InputEventSource::getInstance(){
static InputEventSource* mInst = nullptr;
if(mInst == nullptr)mInst = new InputEventSource();
return *mInst;
}

View File

@ -7,6 +7,7 @@
#include <core/looper.h>
#include <core/uievents.h>
#include <core/inputdevice.h>
#include <core/neverdestroyed.h>
#include <unordered_map>
#include <mutex>
@ -30,6 +31,7 @@ private:
void doEventsConsume();
protected:
InputEventSource();
friend NeverDestroyed<InputEventSource>;
void onDeviceChanged(const INPUTEVENT*es);
public:
static InputEventSource& getInstance();

View File

@ -318,7 +318,7 @@ int Looper::pollInner(int timeoutMillis) {
}
for(auto it=mEventHandlers.begin();it!=mEventHandlers.end();it++){
EventHandler*es=(*it);
if(es&&(es->mRemoved==0)&&(es->checkEvents()>0)){
if(es&&((es->mFlags&1)==0)&&(es->checkEvents()>0)){
es->handleEvents();
}
}
@ -396,9 +396,10 @@ int Looper::pollAll(int timeoutMillis, int* outFd, int* outEvents, void** outDat
void Looper::doIdleHandlers(){
for(auto it=mHandlers.begin();it!=mHandlers.end();it++){
if((*it)->mFlags==1){
const int flags = (*it)->mFlags;
if(flags&1){
LOGD("delete Handler %p",(*it));
delete *it;
if(flags&2)delete *it;
it= mHandlers.erase(it);
continue;
}
@ -617,7 +618,9 @@ void Looper::addHandler(MessageHandler*handler){
void Looper::removeHandler(MessageHandler*handler){
for(auto it=mHandlers.begin();it!=mHandlers.end();it++){
if((*it)==handler){
handler->mFlags=1;
handler->mFlags|=1;
if((handler->mFlags&2)==0)//handler is not owned by looper,erase at once
mHandlers.erase(it);
break;
}
}
@ -630,19 +633,22 @@ void Looper::addEventHandler(const EventHandler*handler){
void Looper::removeEventHandler(const EventHandler*handler){
for(auto it=mEventHandlers.begin();it!=mEventHandlers.end();it++){
if((*it)==handler){
(*it)->mRemoved =true;
(*it)->mFlags |=1;
if((handler->mFlags&2)==0)//handler is not owned by looper,erase at once
mEventHandlers.erase(it);
break;
}
}
}
void Looper::removeEventHandlers(){
for(auto it=mEventHandlers.begin();it!=mEventHandlers.end();it++){
if((*it)->mRemoved){
delete (*it);
it = mEventHandlers.erase(it);
}
}
for(auto it=mEventHandlers.begin();it!=mEventHandlers.end();it++){
const int flags = (*it)->mFlags;
if(flags&1){
delete (*it);
it = mEventHandlers.erase(it);
}
}
}
void Looper::removeMessages(const MessageHandler* handler) {
@ -705,10 +711,24 @@ MessageHandler::MessageHandler(){
MessageHandler::~MessageHandler(){
}
void MessageHandler::setOwned(bool looper){
if(looper)mFlags|=2;
else mFlags&=~2;
}
void MessageHandler::handleIdle(){
}
EventHandler::EventHandler(){
mFlags = 0;
}
EventHandler::~EventHandler(){
}
void EventHandler::setOwned(bool looper){
if(looper)mFlags|=2;
else mFlags&=~2;
}
}

View File

@ -56,6 +56,7 @@ private:
friend class Looper;
protected:
MessageHandler();
void setOwned(bool looper);
virtual ~MessageHandler();
public:
virtual void handleMessage(Message& message)=0;
@ -64,10 +65,12 @@ public:
class EventHandler{
protected:
int mRemoved=0;
int mFlags;
friend class Looper;
protected:
EventHandler();
virtual ~EventHandler();
void setOwned(bool looper);
public:
virtual int checkEvents()=0;
virtual int handleEvents()=0;

View File

@ -9,7 +9,7 @@ class NeverDestroyed {
public:
template <typename... Args>
explicit NeverDestroyed(Args&&... args){
new (m_storage) T(std::forward<Args>(args)...);
new (storagePointer()) T(std::forward<Args>(args)...);
}
NeverDestroyed(const NeverDestroyed&) = delete;
@ -18,12 +18,14 @@ public:
~NeverDestroyed(){
get()->~T();
}
T* get() const { return const_cast<T*>(reinterpret_cast<const T*>(m_storage)); }
T* operator->() const { return get(); }
T& operator*() const { return *get(); }
T* get() const { return storagePointer();}
T* operator->() const { return storagePointer(); }
T& operator*() const { return *storagePointer(); }
private:
alignas(T) unsigned char m_storage[sizeof(T)];
//typename std::aligned_storage<sizeof(T), std::alignment_of<T>::value>::type m_storage;
using PointerType = typename std::remove_const<T>::type*;
//alignas(T) unsigned char m_storage[sizeof(T)];
typename std::aligned_storage<sizeof(T), std::alignment_of<T>::value>::type m_storage;
PointerType storagePointer() const { return const_cast<PointerType>(reinterpret_cast<const T*>(&m_storage)); }
};
}/*endof namespace*/
#endif

View File

@ -9,6 +9,7 @@ namespace cdroid{
UIEventSource::UIEventSource(View*v,std::function<void()>r){
mAttachedView = dynamic_cast<ViewGroup*>(v);
mLayoutRunner = r;
setOwned(true);
}
UIEventSource::~UIEventSource(){
@ -36,7 +37,7 @@ void UIEventSource::handleCompose(){
int UIEventSource::handleRunnables(){
int count=0;
GraphDevice::getInstance().lock();
if ( (mRemoved==false) && mAttachedView && mAttachedView->isAttachedToWindow()){
if ( ((mFlags&1)==0) && mAttachedView && mAttachedView->isAttachedToWindow()){
if(mAttachedView->isLayoutRequested())
mLayoutRunner();
mRunnables.remove_if([](const RUNNER&r)->bool{
@ -44,14 +45,14 @@ int UIEventSource::handleRunnables(){
});
const nsecs_t nowms = SystemClock::uptimeMillis();
//maybe user will removed runnable itself in its runnable'proc,so we use removed flag to flag it
while(mRunnables.size() && (mRemoved==false)){
while(mRunnables.size() && ((mFlags&1)==0)){
RUNNER runner = mRunnables.front();
if(runner.time > nowms)break;
mRunnables.pop_front();
if(runner.run)runner.run();
count++;
count++;
}
if((mRemoved==false) && mAttachedView->isDirty() && mAttachedView->getVisibility()==View::VISIBLE){
if(((mFlags&1)==0) && mAttachedView->isDirty() && mAttachedView->getVisibility()==View::VISIBLE){
((Window*)mAttachedView)->draw();
GraphDevice::getInstance().flip();
}

View File

@ -98,7 +98,6 @@ public:
//////////////////////////////////////////////////////////////////////////////////////////
Choreographer*Choreographer::mInst=nullptr;
long Choreographer::sFrameDelay = DEFAULT_FRAME_DELAY;
Choreographer::Choreographer(){
@ -110,9 +109,8 @@ Choreographer::Choreographer(){
mCallbackQueues[i]=new CallbackQueue;
}
static NeverDestroyed<Choreographer>mInst;
Choreographer&Choreographer::getInstance(){
if(mInst==nullptr)
mInst=new Choreographer();
return *mInst;
}

View File

@ -1,6 +1,7 @@
#ifndef __CHOREO_GRAPHER_H__
#define __CHOREO_GRAPHER_H__
#include <core/looper.h>
#include <core/neverdestroyed.h>
#include <drawables/drawable.h>
namespace cdroid{
class Choreographer{
@ -19,8 +20,8 @@ private:
long mLastFrameTimeNanos;
long mFrameIntervalNanos;
class CallbackQueue* mCallbackQueues[CALLBACK_LAST];
static Choreographer *mInst;
static long sFrameDelay;
friend NeverDestroyed<Choreographer>;
Choreographer();
void removeCallbacksInternal(int callbackType,const Runnable* action, void* token);
void postCallbackDelayedInternal(int callbackType,void* action, void* token, long delayMillis);