mirror of
https://gitee.com/houstudio/Cdroid.git
synced 2024-12-01 19:58:14 +08:00
add callckbase for runnable implmentation
This commit is contained in:
parent
01f9f55aa5
commit
1396387c99
4
src/gui/core/callbackbase.cc
Executable file
4
src/gui/core/callbackbase.cc
Executable file
@ -0,0 +1,4 @@
|
||||
#include <core/callbackbase.h>
|
||||
namespace cdroid{
|
||||
std::atomic_int mCallbackID(0);
|
||||
}
|
45
src/gui/core/callbackbase.h
Executable file
45
src/gui/core/callbackbase.h
Executable file
@ -0,0 +1,45 @@
|
||||
#pragma once
|
||||
#include <functional>
|
||||
#include <type_traits>
|
||||
#include <atomic>
|
||||
namespace cdroid{
|
||||
|
||||
extern std::atomic_int mCallbackID;
|
||||
|
||||
template<typename R,typename... Args>
|
||||
class CallbackBase{
|
||||
private:
|
||||
using Functor=std::function<R(Args...)>;
|
||||
Functor fun;
|
||||
long mID;
|
||||
public:
|
||||
CallbackBase(){fun=nullptr_t();mID=mCallbackID++;}
|
||||
CallbackBase(const Functor&a):CallbackBase(){
|
||||
fun=a;
|
||||
}
|
||||
CallbackBase&operator=(const Functor&a){
|
||||
fun=a;
|
||||
return *this;
|
||||
}
|
||||
CallbackBase&operator=(const CallbackBase&b){
|
||||
mID=b.mID;
|
||||
fun=b.fun;
|
||||
return *this;
|
||||
}
|
||||
bool operator==(const CallbackBase&b)const{
|
||||
return mID==b.mID;
|
||||
}
|
||||
operator bool()const{ return fun!=nullptr; }
|
||||
operator int() const{ return mID; }
|
||||
bool operator==(nullptr_t)const{
|
||||
return fun==nullptr;
|
||||
}
|
||||
bool operator!=(nullptr_t)const{
|
||||
return fun!=nullptr;
|
||||
}
|
||||
R operator()(Args...args)const{
|
||||
return fun(std::forward<Args>(args)...);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -85,7 +85,7 @@ namespace cdroid{
|
||||
CallbackRecord* predecessor = nullptr;
|
||||
for (CallbackRecord* callback = mHead; callback != nullptr;) {
|
||||
CallbackRecord* next = callback->next;
|
||||
if ((/*action == nullptr ||*/ callback->action.ID == action.ID)
|
||||
if ((/*action == nullptr ||*/ callback->action == action)
|
||||
&& (token == 0 || callback->token == token)) {
|
||||
if (predecessor != nullptr) {
|
||||
predecessor->next = next;
|
||||
|
@ -5,43 +5,12 @@
|
||||
#include <functional>
|
||||
#include <cairomm/refptr.h>
|
||||
#include <cairomm/surface.h>
|
||||
|
||||
#include <core/callbackbase.h>
|
||||
using namespace Cairo;
|
||||
|
||||
namespace cdroid{
|
||||
class Runnable{
|
||||
public:
|
||||
int ID;
|
||||
std::function<void()>run;
|
||||
Runnable(){
|
||||
run=nullptr;
|
||||
}
|
||||
Runnable(const Runnable&b){
|
||||
run=b.run;
|
||||
ID=b.ID;
|
||||
}
|
||||
Runnable(const std::function<void()>&f){
|
||||
run=f;
|
||||
}
|
||||
void operator=(const std::function<void()>&f){
|
||||
run=f;
|
||||
}
|
||||
void operator=(nullptr_t){
|
||||
run=nullptr;
|
||||
}
|
||||
bool operator==(nullptr_t)const{
|
||||
return run==nullptr;
|
||||
}
|
||||
bool operator!=(nullptr_t)const{
|
||||
return run!=nullptr;
|
||||
}
|
||||
explicit operator bool()const{
|
||||
return run!=nullptr;
|
||||
}
|
||||
void operator()(){
|
||||
run();
|
||||
}
|
||||
};
|
||||
|
||||
typedef CallbackBase<void> Runnable;
|
||||
class Drawable;
|
||||
class ColorStateList;
|
||||
class Context{
|
||||
|
@ -10,7 +10,6 @@ namespace cdroid{
|
||||
|
||||
UIEventSource::UIEventSource(View*v){
|
||||
mAttachedView=v;
|
||||
mID=0;
|
||||
}
|
||||
|
||||
UIEventSource::~UIEventSource(){
|
||||
@ -28,18 +27,23 @@ int UIEventSource::handleEvents(){
|
||||
}
|
||||
if(GraphDevice::getInstance().needCompose())
|
||||
GraphDevice::getInstance().ComposeSurfaces();
|
||||
for(auto it=mRunnables.begin();it!=mRunnables.end();it++){
|
||||
LOGV_IF(it->removed,"remove %d",(int)it->run);
|
||||
if(it->removed)it=mRunnables.erase(it);
|
||||
}
|
||||
if(hasDelayedRunners()){
|
||||
RUNNER runner=mRunnables.front();
|
||||
runner.run();
|
||||
runner.run();//maybe user will removed runnable itself in its runnable'proc,so we use removed flag to flag it
|
||||
LOGV("remove %d",(int)runner.run);
|
||||
mRunnables.pop_front();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void UIEventSource::post(Runnable& run,DWORD delayedtime){
|
||||
void UIEventSource::post(const Runnable& run,uint32_t delayedtime){
|
||||
RUNNER runner;
|
||||
runner.removed=false;
|
||||
runner.time=SystemClock::uptimeMillis()+delayedtime;
|
||||
run.ID=mID++;
|
||||
runner.run=run;
|
||||
for(auto itr=mRunnables.begin();itr!=mRunnables.end();itr++){
|
||||
if(runner.time<itr->time){
|
||||
@ -58,9 +62,9 @@ bool UIEventSource::hasDelayedRunners()const{
|
||||
}
|
||||
|
||||
void UIEventSource::removeCallbacks(const Runnable& what){
|
||||
mRunnables.remove_if([&](const RUNNER& m)->bool{
|
||||
return (m.run.ID==what.ID);
|
||||
});
|
||||
for(auto it=mRunnables.begin();it!=mRunnables.end();it++){
|
||||
if(it->run==what) it->removed=true;
|
||||
}
|
||||
}
|
||||
|
||||
}//end namespace
|
||||
|
@ -8,10 +8,10 @@ namespace cdroid{
|
||||
|
||||
class UIEventSource:public EventHandler{
|
||||
private:
|
||||
int mID;
|
||||
typedef struct{
|
||||
nsecs_t time;
|
||||
Runnable run;
|
||||
nsecs_t time;
|
||||
bool removed;
|
||||
Runnable run;
|
||||
}RUNNER;
|
||||
std::list<RUNNER>mRunnables;
|
||||
View*mAttachedView;
|
||||
@ -22,7 +22,7 @@ public:
|
||||
bool processEvents();
|
||||
int checkEvents()override;
|
||||
int handleEvents()override;
|
||||
void post(Runnable& run,DWORD delay=0);
|
||||
void post(const Runnable& run,uint32_t delay=0);
|
||||
void removeCallbacks(const Runnable& what);
|
||||
};
|
||||
|
||||
|
@ -387,7 +387,7 @@ void AdapterView::selectionChanged(){
|
||||
// by posting. This ensures that the view tree is
|
||||
// in a consistent state and is able to accommodate
|
||||
// new layout or invalidate requests.
|
||||
if (mSelectionNotifier == nullptr) {
|
||||
if (mSelectionNotifier==nullptr) {
|
||||
mSelectionNotifier =[this](){
|
||||
mPendingSelectionNotifier = nullptr;
|
||||
if (mDataChanged /*&& getViewRootImpl() && getViewRootImpl().isLayoutRequested()*/) {
|
||||
|
@ -3422,18 +3422,19 @@ bool View::onTouchEvent(MotionEvent& mt){
|
||||
return false;
|
||||
}
|
||||
|
||||
void View::postOnAnimation(Runnable action){
|
||||
void View::postOnAnimation(const Runnable& action){
|
||||
postDelayed(action,10);
|
||||
}
|
||||
void View::postOnAnimationDelayed(Runnable action, long delayMillis){
|
||||
|
||||
void View::postOnAnimationDelayed(const Runnable& action, uint32_t delayMillis){
|
||||
postDelayed(action,delayMillis);
|
||||
}
|
||||
|
||||
void View::post(Runnable& what){
|
||||
void View::post(const Runnable& what){
|
||||
postDelayed(what,0);
|
||||
}
|
||||
|
||||
void View::postDelayed(Runnable& what,uint32_t delay){
|
||||
void View::postDelayed(const Runnable& what,uint32_t delay){
|
||||
View*root=getRootView();
|
||||
if(root&&(root!=this))root->postDelayed(what,delay);
|
||||
}
|
||||
|
@ -354,8 +354,8 @@ protected:
|
||||
bool awakenScrollBars();
|
||||
bool awakenScrollBars(int startDelay, bool invalidate);
|
||||
|
||||
void postOnAnimation(Runnable action);
|
||||
void postOnAnimationDelayed(Runnable action, long delayMillis);
|
||||
void postOnAnimation(const Runnable& action);
|
||||
void postOnAnimationDelayed(const Runnable& action, uint32_t delayMillis);
|
||||
virtual void onSizeChanged(int w,int h,int oldw,int oldh);
|
||||
virtual void onScrollChanged(int l, int t, int oldl, int oldt);
|
||||
virtual void onLayout(bool ,int,int,int,int);
|
||||
@ -679,10 +679,10 @@ public:
|
||||
virtual bool onGenericMotionEvent(MotionEvent& event);
|
||||
virtual void onHoverChanged(bool hovered);
|
||||
|
||||
void post(Runnable& what);
|
||||
void post(const Runnable& what);
|
||||
void post(const std::function<void()>&what);
|
||||
void postDelayed(const std::function<void()>&what,uint32_t delay=0);
|
||||
virtual void postDelayed(Runnable& what,uint32_t delay=0);
|
||||
virtual void postDelayed(const Runnable& what,uint32_t delay=0);
|
||||
virtual void removeCallbacks(const Runnable& what);
|
||||
|
||||
virtual int getBaseline();
|
||||
|
@ -283,7 +283,7 @@ bool Window::onKeyDown(int keyCode,KeyEvent& evt){
|
||||
}
|
||||
|
||||
|
||||
void Window::postDelayed(Runnable& what,uint32_t delay){
|
||||
void Window::postDelayed(const Runnable& what,uint32_t delay){
|
||||
if(source)source->post(what,delay);
|
||||
}
|
||||
|
||||
|
@ -71,7 +71,7 @@ public:
|
||||
sendMessage(this,msgid,wParam,lParam,delayedtime);
|
||||
}
|
||||
virtual void sendMessage(View*v,DWORD msgid,DWORD wParam,ULONG lParam,DWORD delayedtime=0)override;*/
|
||||
void postDelayed(Runnable& what,uint32_t delay)override;
|
||||
void postDelayed(const Runnable& what,uint32_t delay)override;
|
||||
void removeCallbacks(const Runnable& what)override;
|
||||
void requestLayout()override;
|
||||
static void broadcast(DWORD msgid,DWORD wParam,ULONG lParam);
|
||||
|
3
tests/gui/CMakeLists.txt
Normal file → Executable file
3
tests/gui/CMakeLists.txt
Normal file → Executable file
@ -1,8 +1,9 @@
|
||||
project(gui_test C CXX)
|
||||
|
||||
set(CMAKE_CXX_STANDARD 11)
|
||||
aux_source_directory(./ SRCS_GUI_TESTS)
|
||||
|
||||
include_directories(
|
||||
./
|
||||
${DEPS_DIR}/include
|
||||
${DEPS_DIR}/include/gui
|
||||
${DEPS_DIR}/include/porting
|
||||
|
38
tests/gui/callback.h
Executable file
38
tests/gui/callback.h
Executable file
@ -0,0 +1,38 @@
|
||||
#pragma once
|
||||
#include <functional>
|
||||
#include <type_traits>
|
||||
#include <atomic>
|
||||
namespace test{
|
||||
static std::atomic_int ID(0);
|
||||
|
||||
template<typename R,typename... Args>
|
||||
class CallbackBase{
|
||||
private:
|
||||
using Functor=std::function<R(Args...)>;
|
||||
Functor fun;
|
||||
long mID;
|
||||
public:
|
||||
CallbackBase(){fun=nullptr_t();mID=ID++;}
|
||||
CallbackBase(const Functor&a):CallbackBase(){
|
||||
fun=a;
|
||||
}
|
||||
CallbackBase&operator=(const Functor&a){
|
||||
fun=a;
|
||||
return *this;
|
||||
}
|
||||
CallbackBase&operator=(const CallbackBase&b){
|
||||
mID=b.mID;
|
||||
fun=b.fun;
|
||||
return *this;
|
||||
}
|
||||
bool operator==(const CallbackBase&b){
|
||||
return mID==b.mID;
|
||||
}
|
||||
operator bool()const{
|
||||
return fun!=nullptr;
|
||||
}
|
||||
R operator()(Args...args)const{
|
||||
return fun(std::forward<Args>(args)...);
|
||||
}
|
||||
};
|
||||
}
|
29
tests/gui/callback_tests.cc
Executable file
29
tests/gui/callback_tests.cc
Executable file
@ -0,0 +1,29 @@
|
||||
#include <gtest/gtest.h>
|
||||
#include <windows.h>
|
||||
#include <ngl_os.h>
|
||||
#include <sys/time.h>
|
||||
#include <core/systemclock.h>
|
||||
#include <cdlog.h>
|
||||
#include <functional>
|
||||
#include <callback.h>
|
||||
|
||||
class CALLBACK:public testing::Test{
|
||||
|
||||
public :
|
||||
virtual void SetUp(){
|
||||
}
|
||||
virtual void TearDown(){
|
||||
}
|
||||
};
|
||||
|
||||
TEST_F(CALLBACK,loop){
|
||||
test::CallbackBase<void> c0([](){});
|
||||
test::CallbackBase<void,int> c1([](int a){printf("a=%d\r\n",a);});
|
||||
test::CallbackBase<void,int,int>cb2([](int a,int b){printf("a=%d,b=%d\r\n",a,b);});
|
||||
test::CallbackBase<int,int,int>cbr2([](int a,int b){return a+b;});
|
||||
c1(123);
|
||||
cb2(123,456);
|
||||
printf("cbr2=%d\r\n",cbr2(234,345));
|
||||
cbr2=[](int a,int b){return a*b;};
|
||||
printf("cbr2=%d\r\n",cbr2(234,345));
|
||||
}
|
Loading…
Reference in New Issue
Block a user