mirror of
https://gitee.com/houstudio/Cdroid.git
synced 2024-11-29 18:59:14 +08:00
fix some modules's atexit
This commit is contained in:
parent
5800616978
commit
163bebcd4d
@ -1,12 +1,15 @@
|
|||||||
#include "atexit.h"
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <memory>
|
||||||
|
#include <core/atexit.h>
|
||||||
namespace cdroid {
|
namespace cdroid {
|
||||||
|
|
||||||
|
static std::vector<std::function<void()>> *mCallbacks = nullptr;
|
||||||
std::vector<std::function<void()>>& AtExit::callbacks() {
|
std::vector<std::function<void()>>& AtExit::callbacks() {
|
||||||
static std::vector<std::function<void()>> callbacks;
|
if(mCallbacks==nullptr)
|
||||||
return callbacks;
|
mCallbacks = new std::vector<std::function<void()>>;
|
||||||
|
return *mCallbacks;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::mutex& AtExit::callbacksMutex() {
|
std::mutex& AtExit::callbacksMutex() {
|
||||||
@ -16,15 +19,20 @@ std::mutex& AtExit::callbacksMutex() {
|
|||||||
|
|
||||||
void AtExit::registerCallback(std::function<void()> callback) {
|
void AtExit::registerCallback(std::function<void()> callback) {
|
||||||
std::lock_guard<std::mutex> lock(callbacksMutex());
|
std::lock_guard<std::mutex> lock(callbacksMutex());
|
||||||
callbacks().push_back(std::move(callback));
|
callbacks().push_back(callback);
|
||||||
|
LOGD("callbacks.size=%d %p",callbacks().size(),&callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AtExit::executeCallbacks() {
|
void AtExit::executeCallbacks() {
|
||||||
std::lock_guard<std::mutex> lock(callbacksMutex());
|
std::lock_guard<std::mutex> lock(callbacksMutex());
|
||||||
std::for_each(callbacks().rbegin(), callbacks().rend(), [](const std::function<void()>& callback) {
|
std::vector<std::function<void()>>&cbks = callbacks();
|
||||||
callback();
|
LOGD("AtExit::executeCallbacks %d",int(cbks.size()));
|
||||||
});
|
for(auto& callback:cbks) {
|
||||||
|
if(callback)callback();
|
||||||
|
}
|
||||||
|
delete mCallbacks;
|
||||||
}
|
}
|
||||||
|
|
||||||
class AtExit::AtExitInitializer{
|
class AtExit::AtExitInitializer{
|
||||||
public:
|
public:
|
||||||
AtExitInitializer();
|
AtExitInitializer();
|
||||||
@ -32,9 +40,8 @@ public:
|
|||||||
|
|
||||||
// Ensure callbacks are executed at exit
|
// Ensure callbacks are executed at exit
|
||||||
AtExit::AtExitInitializer::AtExitInitializer(){
|
AtExit::AtExitInitializer::AtExitInitializer(){
|
||||||
std::atexit([] {
|
LOGD("**AtExitInitializer::AtExitInitializer");
|
||||||
AtExit::executeCallbacks();
|
atexit(AtExit::executeCallbacks);
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
AtExit::AtExitInitializer atExitInitializer;
|
AtExit::AtExitInitializer atExitInitializer;
|
||||||
|
@ -369,7 +369,7 @@ int Typeface::loadFromFontConfig() {
|
|||||||
mSystemLang = lang;
|
mSystemLang = lang;
|
||||||
for (int i=0; fs && i < fs->nfont; i++) {
|
for (int i=0; fs && i < fs->nfont; i++) {
|
||||||
FcPattern *pat = fs->fonts[i];//FcPatternDuplicate(fs->fonts[i]);
|
FcPattern *pat = fs->fonts[i];//FcPatternDuplicate(fs->fonts[i]);
|
||||||
Typeface *tf = new Typeface(*pat);
|
Typeface* tf = new Typeface(*pat);
|
||||||
const std::string family = tf->getFamily();
|
const std::string family = tf->getFamily();
|
||||||
const std::string style = tf->getStyleName();
|
const std::string style = tf->getStyleName();
|
||||||
std::string font = tf->mFileName;
|
std::string font = tf->mFileName;
|
||||||
|
@ -1,159 +0,0 @@
|
|||||||
#include <core/context.h>
|
|
||||||
#include <cairomm/surface.h>
|
|
||||||
#include <image-decoders/imagedecoder.h>
|
|
||||||
#include <gif_lib.h>
|
|
||||||
#include <cdlog.h>
|
|
||||||
|
|
||||||
namespace cdroid{
|
|
||||||
|
|
||||||
struct PRIVATE{
|
|
||||||
std::vector<int>delays;
|
|
||||||
GifFileType*gif;
|
|
||||||
}GIFPrivate;
|
|
||||||
|
|
||||||
GIFDecoder::GIFDecoder(std::istream&stm):ImageDecoder(stm){
|
|
||||||
mPrivate = new PRIVATE;
|
|
||||||
mPrivate->gif=nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
GIFDecoder::~GIFDecoder(){
|
|
||||||
DGifCloseFile(mPrivate->gif,nullptr);
|
|
||||||
delete mPrivate;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define ARGB(a, r, g, b) ( ((a) & 0xff) << 24 ) | ( ((r) & 0xff) << 16 ) | ( ((g) & 0xff) << 8 ) | ((b) & 0xff)
|
|
||||||
#define DISPOSE(ext) (((ext)->Bytes[0] & 0x1c) >> 2)
|
|
||||||
#define TRANS_INDEX(ext) ((ext)->Bytes[3])
|
|
||||||
#define TRANSPARENCY(ext) ((ext)->Bytes[0] & 1)
|
|
||||||
#define DELAY(ext) (10*((ext)->Bytes[2] << 8 | (ext)->Bytes[1]))
|
|
||||||
|
|
||||||
static int GIFRead(GifFileType *gifFile, GifByteType *buff, int rdlen){
|
|
||||||
std::istream*is=(std::istream*)gifFile->UserData;
|
|
||||||
is->read((char*)buff,rdlen);
|
|
||||||
return is->gcount();
|
|
||||||
}
|
|
||||||
|
|
||||||
static int gifDrawFrame(GifFileType*gif,int current_frame,size_t pxstride,uint8_t *pixels,bool force_DISPOSE_1);
|
|
||||||
|
|
||||||
int GIFDecoder::decode(bool sizeOnly){
|
|
||||||
int err;
|
|
||||||
GifFileType*gifFileType = DGifOpen(istream,GIFRead,&err);
|
|
||||||
LOGE_IF(gifFileType==nullptr,"git load failed");
|
|
||||||
if(gifFileType==nullptr)return 0;
|
|
||||||
DGifSlurp(gifFileType);
|
|
||||||
|
|
||||||
mFrameCount = gifFileType->ImageCount;
|
|
||||||
mPrivate->gif = gifFileType;
|
|
||||||
mImageWidth = gifFileType->SWidth;
|
|
||||||
mImageHeight= gifFileType->SHeight;
|
|
||||||
LOGD("GIF %d frames loaded size(%dx%d)",mFrameCount,mImageWidth,mImageHeight);
|
|
||||||
return mFrameCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
int GIFDecoder::readImage(Cairo::RefPtr<Cairo::ImageSurface>image,int frameIndex){
|
|
||||||
const int duration = gifDrawFrame(mPrivate->gif,frameIndex,image->get_stride(),image->get_data(),false);
|
|
||||||
if(frameIndex>=mPrivate->delays.size()){
|
|
||||||
mPrivate->delays.push_back(duration);
|
|
||||||
}
|
|
||||||
return duration;
|
|
||||||
}
|
|
||||||
|
|
||||||
int GIFDecoder::getFrameDuration(int frameIndex)const{
|
|
||||||
return mPrivate->delays.at(frameIndex);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int gifDrawFrame(GifFileType*gif,int current_frame,size_t pxstride,uint8_t *pixels,bool force_DISPOSE_1) {
|
|
||||||
GifColorType *bg;
|
|
||||||
GifColorType *color;
|
|
||||||
SavedImage *frame;
|
|
||||||
ExtensionBlock *ext = nullptr;
|
|
||||||
GifImageDesc *frameInfo;
|
|
||||||
ColorMapObject *colorMap;
|
|
||||||
uint32_t *line;
|
|
||||||
int width, height, x, y, j;
|
|
||||||
uint8_t *px = (uint8_t*)pixels;
|
|
||||||
width = gif->SWidth;
|
|
||||||
height = gif->SHeight;
|
|
||||||
frame = &(gif->SavedImages[current_frame]);
|
|
||||||
frameInfo = &(frame->ImageDesc);
|
|
||||||
colorMap = frameInfo->ColorMap?frameInfo->ColorMap:gif->SColorMap;
|
|
||||||
|
|
||||||
bg = &colorMap->Colors[gif->SBackGroundColor];
|
|
||||||
for (j = 0; j < frame->ExtensionBlockCount; j++) {
|
|
||||||
if (frame->ExtensionBlocks[j].Function == GRAPHICS_EXT_FUNC_CODE) {
|
|
||||||
ext = &(frame->ExtensionBlocks[j]);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// For DISPOSE = 1, we assume its been drawn
|
|
||||||
if (ext && DISPOSE(ext) == 1 && force_DISPOSE_1 && current_frame > 0) {
|
|
||||||
current_frame = current_frame - 1;
|
|
||||||
gifDrawFrame(gif,current_frame,pxstride, pixels, true);
|
|
||||||
} else if (ext && DISPOSE(ext) == 2 && bg) {
|
|
||||||
for (y = 0; y < height; y++) {
|
|
||||||
line = (uint32_t *) px;
|
|
||||||
for (x = 0; x < width; x++) {
|
|
||||||
line[x] = ARGB(255, bg->Red, bg->Green, bg->Blue);
|
|
||||||
}
|
|
||||||
px = (px + pxstride);
|
|
||||||
}
|
|
||||||
current_frame=(current_frame+1)%gif->ImageCount;
|
|
||||||
} else if (ext && DISPOSE(ext) == 3 && current_frame > 1) {
|
|
||||||
current_frame = current_frame - 2;
|
|
||||||
gifDrawFrame(gif,current_frame,pxstride, pixels, true);
|
|
||||||
}else current_frame=(current_frame+1)%gif->ImageCount;
|
|
||||||
px = (uint8_t*)pixels;
|
|
||||||
|
|
||||||
const bool isTransparent = TRANSPARENCY(ext);
|
|
||||||
const int transparentIndex = TRANS_INDEX(ext);
|
|
||||||
if (frameInfo->Interlace) {
|
|
||||||
int n = 0, inc = 8, p = 0,loc=0;
|
|
||||||
px = (px + pxstride * frameInfo->Top);
|
|
||||||
for (y = frameInfo->Top; y < frameInfo->Top + frameInfo->Height; y++) {
|
|
||||||
for (x = frameInfo->Left; x < frameInfo->Left + frameInfo->Width; x++) {
|
|
||||||
loc = (y - frameInfo->Top) * frameInfo->Width + (x - frameInfo->Left);
|
|
||||||
if (ext && isTransparent && (frame->RasterBits[loc]==transparentIndex)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
color = (ext && frame->RasterBits[loc] == transparentIndex) ? bg
|
|
||||||
: &colorMap->Colors[frame->RasterBits[loc]];
|
|
||||||
if (color)
|
|
||||||
line[x] = ARGB(255U, color->Red, color->Green, color->Blue);
|
|
||||||
}
|
|
||||||
px = (px + pxstride * inc);
|
|
||||||
n += inc;
|
|
||||||
if (n >= frameInfo->Height) {
|
|
||||||
n = 0;
|
|
||||||
switch (p) {
|
|
||||||
case 0:
|
|
||||||
px = (pixels + pxstride * (4 + frameInfo->Top));
|
|
||||||
inc = 8; p++; break;
|
|
||||||
case 1:
|
|
||||||
px = (pixels + pxstride * (2 + frameInfo->Top));
|
|
||||||
inc = 4; p++; break;
|
|
||||||
case 2:
|
|
||||||
px = (pixels + pxstride * (1 + frameInfo->Top));
|
|
||||||
inc = 2; p++; break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
px = ( px + pxstride * frameInfo->Top);
|
|
||||||
for (y = frameInfo->Top; y < frameInfo->Top + frameInfo->Height; y++) {
|
|
||||||
line = (uint32_t *) px;
|
|
||||||
for (x = frameInfo->Left; x < frameInfo->Left + frameInfo->Width; x++) {
|
|
||||||
int loc = (y - frameInfo->Top) * frameInfo->Width + (x - frameInfo->Left);
|
|
||||||
if (ext && isTransparent &&(frame->RasterBits[loc] == transparentIndex)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
color = (ext && frame->RasterBits[loc] == transparentIndex) ? bg
|
|
||||||
: &colorMap->Colors[frame->RasterBits[loc]];
|
|
||||||
if (color)
|
|
||||||
line[x] = ARGB(255U, color->Red, color->Green, color->Blue);
|
|
||||||
}
|
|
||||||
px +=pxstride;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return DELAY(ext);
|
|
||||||
}
|
|
||||||
}/*endof namespace*/
|
|
@ -5,24 +5,19 @@
|
|||||||
#include <framesequence.h>
|
#include <framesequence.h>
|
||||||
#include <gui/cdroid.h>
|
#include <gui/cdroid.h>
|
||||||
#include <core/app.h>
|
#include <core/app.h>
|
||||||
|
#include <core/textutils.h>
|
||||||
int main(int argc,const char*argv[]){
|
int main(int argc,const char*argv[]){
|
||||||
cdroid::App app(argc,argv);
|
cdroid::App app(argc,argv);
|
||||||
#if 0
|
#if 1
|
||||||
std::unique_ptr<std::ifstream> fstrm = std::make_unique<std::ifstream>(argv[1]);
|
const char*fname =(argc>1)?argv[1]:"/home/houzh/pf.jpg";
|
||||||
std::unique_ptr<std::istream> istm = std::move(fstrm);
|
std::ifstream fstrm (fname);
|
||||||
cdroid::GIFDecoder*dec = new cdroid::GIFDecoder(std::move(istm));
|
cdroid::ImageDecoder*dec=nullptr;
|
||||||
dec->load();
|
if(TextUtils::endWith(fname,"png")) dec=new cdroid::PNGDecoder(fstrm);
|
||||||
const int frmCount = dec->getFrameCount();
|
else dec=new cdroid::JPEGDecoder(fstrm);
|
||||||
LOGD("imageinfo:%dx%dx%d",dec->getWidth(),dec->getHeight(),frmCount);
|
Cairo::RefPtr<Cairo::ImageSurface>image=dec->decode(1.234);
|
||||||
Cairo::RefPtr<Cairo::ImageSurface>image
|
LOGD("imageinfo:%dx%d",dec->getWidth(),dec->getHeight());
|
||||||
=Cairo::ImageSurface::create(Cairo::Surface::Format::ARGB32,dec->getWidth(),dec->getHeight());
|
image->write_to_png("111.png");
|
||||||
for(int loop=0;loop<10;loop++){
|
//cdroid::FrameSequence*seq=cdroid::FrameSequence::create(&fin);
|
||||||
for(int i=0;i<frmCount;i++)
|
|
||||||
dec->readImage(image,i);
|
|
||||||
LOGD("loop %d",loop);
|
|
||||||
}
|
|
||||||
|
|
||||||
cdroid::FrameSequence*seq=cdroid::FrameSequence::create(&fin);
|
|
||||||
#else
|
#else
|
||||||
Window*w=new Window(0,0,-1,-1);
|
Window*w=new Window(0,0,-1,-1);
|
||||||
AnimatedImageDrawable*ad=new AnimatedImageDrawable(&app,app.getParam(0,"./Honeycam1.gif"));
|
AnimatedImageDrawable*ad=new AnimatedImageDrawable(&app,app.getParam(0,"./Honeycam1.gif"));
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
#include <view/keyevent.h>
|
#include <view/keyevent.h>
|
||||||
#include <view/motionevent.h>
|
#include <view/motionevent.h>
|
||||||
#include <core/inputdevice.h>
|
#include <core/inputdevice.h>
|
||||||
|
#include <core/atexit.h>
|
||||||
// --- InputEvent ---
|
// --- InputEvent ---
|
||||||
namespace cdroid{
|
namespace cdroid{
|
||||||
|
|
||||||
@ -57,8 +58,10 @@ void InputEvent::recycle(){
|
|||||||
PooledInputEventFactory*PooledInputEventFactory::mInst=nullptr;
|
PooledInputEventFactory*PooledInputEventFactory::mInst=nullptr;
|
||||||
|
|
||||||
PooledInputEventFactory& PooledInputEventFactory::getInstance(){
|
PooledInputEventFactory& PooledInputEventFactory::getInstance(){
|
||||||
if(nullptr==mInst)
|
if(nullptr==mInst){
|
||||||
mInst = new PooledInputEventFactory(20);
|
mInst = new PooledInputEventFactory(20);
|
||||||
|
AtExit::registerCallback([](){delete mInst;});
|
||||||
|
}
|
||||||
return *mInst;
|
return *mInst;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -67,11 +70,11 @@ PooledInputEventFactory::PooledInputEventFactory(size_t maxPoolSize) :
|
|||||||
}
|
}
|
||||||
|
|
||||||
PooledInputEventFactory::~PooledInputEventFactory() {
|
PooledInputEventFactory::~PooledInputEventFactory() {
|
||||||
for (size_t i = 0; i < mKeyEventPool.size(); i++) {
|
while(!mKeyEventPool.empty()) {
|
||||||
delete mKeyEventPool.front();
|
delete mKeyEventPool.front();
|
||||||
mKeyEventPool.pop();
|
mKeyEventPool.pop();
|
||||||
}
|
}
|
||||||
for (size_t i = 0; i < mMotionEventPool.size(); i++) {
|
while(!mMotionEventPool.empty()) {
|
||||||
delete mMotionEventPool.front();
|
delete mMotionEventPool.front();
|
||||||
mMotionEventPool.pop();
|
mMotionEventPool.pop();
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
#include <view/layoutinflater.h>
|
#include <view/layoutinflater.h>
|
||||||
#include <view/viewgroup.h>
|
#include <view/viewgroup.h>
|
||||||
|
#include <core/atexit.h>
|
||||||
#include <cdroid.h>
|
#include <cdroid.h>
|
||||||
#include <expat.h>
|
#include <expat.h>
|
||||||
#include <cdlog.h>
|
#include <cdlog.h>
|
||||||
@ -20,7 +21,7 @@ LayoutInflater*LayoutInflater::from(Context*context) {
|
|||||||
LayoutInflater*flater = new LayoutInflater(context);
|
LayoutInflater*flater = new LayoutInflater(context);
|
||||||
it = mMaps.insert(std::pair<Context*,LayoutInflater*>(context,flater)).first;
|
it = mMaps.insert(std::pair<Context*,LayoutInflater*>(context,flater)).first;
|
||||||
if( mMaps.size() ==1) {
|
if( mMaps.size() ==1) {
|
||||||
atexit([]() {
|
AtExit::registerCallback([]() {
|
||||||
INFLATERMAPPER& fmap = LayoutInflater::getInflaterMap();
|
INFLATERMAPPER& fmap = LayoutInflater::getInflaterMap();
|
||||||
STYLEMAPPER& smap = getStyleMap();
|
STYLEMAPPER& smap = getStyleMap();
|
||||||
fmap.clear();
|
fmap.clear();
|
||||||
@ -28,7 +29,6 @@ LayoutInflater*LayoutInflater::from(Context*context) {
|
|||||||
for(auto m:mMaps)
|
for(auto m:mMaps)
|
||||||
delete m.second;
|
delete m.second;
|
||||||
mMaps.clear();
|
mMaps.clear();
|
||||||
std::cout<<"LayoutInflater::Destroied!"<<std::endl;
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,4 +4,4 @@ find_package(GTEST)
|
|||||||
if (BUILD_CDROID_TESTS AND GTEST_FOUND)
|
if (BUILD_CDROID_TESTS AND GTEST_FOUND)
|
||||||
add_subdirectory(gui)
|
add_subdirectory(gui)
|
||||||
add_subdirectory(porting)
|
add_subdirectory(porting)
|
||||||
endif(BUILD_CDROID_TESTS)
|
endif(BUILD_CDROID_TESTS AND GTEST_FOUND)
|
||||||
|
Loading…
Reference in New Issue
Block a user