Review IdleRegister (#4892)

This turns `IdleRegister::add()` into a template function to make the
provided function pointers type safe. It also adds a `delete_data`
parameter to manage the provided data pointer even in `destroy()`.
This commit is contained in:
Flössie 2018-10-28 13:12:01 +01:00
parent 7038104a20
commit 5906329485
27 changed files with 708 additions and 697 deletions

View File

@ -50,12 +50,10 @@ struct NLParams {
Glib::ustring queueErrorMessage;
};
int bqnotifylistenerUI (void* data)
bool bqnotifylistenerUI(NLParams* params)
{
NLParams* params = static_cast<NLParams*>(data);
params->listener->queueSizeChanged (params->qsize, params->queueEmptied, params->queueError, params->queueErrorMessage);
delete params;
return 0;
return false;
}
}
@ -438,16 +436,12 @@ void BatchQueue::cancelItems (const std::vector<ThumbBrowserEntryBase*>& items)
if (entry->thumbnail)
entry->thumbnail->imageRemovedFromQueue ();
const auto func = [](gpointer data) -> gboolean {
const BatchQueueEntry* const bqe = static_cast<BatchQueueEntry*>(data);
const auto func = [](BatchQueueEntry* bqe) -> bool {
::g_remove(bqe->savedParamsFile.c_str());
delete bqe;
return FALSE;
return false;
};
idle_register.add(func, entry);
idle_register.add<BatchQueueEntry>(func, entry, true);
}
for (const auto entry : fd)
@ -608,12 +602,14 @@ void BatchQueue::setProgress(double p)
}
// No need to acquire the GUI, setProgressUI will do it
const auto func = [](gpointer data) -> gboolean {
static_cast<BatchQueue*>(data)->redraw();
return FALSE;
const auto func =
[](BatchQueue* bq) -> bool
{
bq->redraw();
return false;
};
idle_register.add(func, this);
idle_register.add<BatchQueue>(func, this, false);
}
void BatchQueue::setProgressStr(const Glib::ustring& str)
@ -643,7 +639,7 @@ void BatchQueue::error(const Glib::ustring& descr)
params->queueEmptied = false;
params->queueError = true;
params->queueErrorMessage = descr;
idle_register.add(bqnotifylistenerUI, params);
idle_register.add<NLParams>(bqnotifylistenerUI, params, true);
}
}
@ -985,7 +981,7 @@ void BatchQueue::notifyListener (bool queueEmptied)
}
params->queueEmptied = queueEmptied;
params->queueError = false;
idle_register.add(bqnotifylistenerUI, params);
idle_register.add<NLParams>(bqnotifylistenerUI, params, true);
}
}

View File

@ -170,13 +170,14 @@ BatchQueuePanel::BatchQueuePanel (FileCatalog* aFileCatalog) : parent(nullptr)
show_all ();
if (batchQueue->loadBatchQueue()) {
const auto func = [](gpointer data) -> gboolean {
static_cast<BatchQueue*>(data)->resizeLoadedQueue();
return FALSE;
const auto func =
[](BatchQueue* bq) -> bool
{
bq->resizeLoadedQueue();
return false;
};
idle_register.add(func, batchQueue, G_PRIORITY_LOW);
idle_register.add<BatchQueue>(func, batchQueue, false, G_PRIORITY_LOW);
}
}

View File

@ -723,8 +723,10 @@ void BayerProcess::FrameCountChanged(int n, int frameNum)
int n;
int frameNum;
};
const auto func = [](gpointer data) -> gboolean {
Data *d = static_cast<Data *>(data);
const auto func =
[](Data* d) -> bool
{
BayerProcess *me = d->me;
me->imageNumber->block (true);
int n = d->n;
@ -744,28 +746,28 @@ void BayerProcess::FrameCountChanged(int n, int frameNum)
me->imageNumberBox->show();
}
me->imageNumber->block (false);
delete d;
return FALSE;
return false;
};
idle_register.add(func, new Data { this, n, frameNum });
idle_register.add<Data>(func, new Data{this, n, frameNum}, true);
}
void BayerProcess::autoContrastChanged (double autoContrast)
{
struct Data {
BayerProcess *me;
BayerProcess* self;
double autoContrast;
};
const auto func = [](gpointer data) -> gboolean {
Data *d = static_cast<Data *>(data);
BayerProcess *me = d->me;
me->disableListener();
me->dualDemosaicContrast->setValue(d->autoContrast);
me->enableListener();
delete d;
return FALSE;
const auto func =
[](Data* data) -> bool
{
BayerProcess* const self = data->self;
self->disableListener();
self->dualDemosaicContrast->setValue(data->autoContrast);
self->enableListener();
return false;
};
idle_register.add(func, new Data { this, autoContrast });
idle_register.add<Data>(func, new Data{this, autoContrast}, true);
}

View File

@ -375,12 +375,14 @@ void BlackWhite::BWChanged (double redbw, double greenbw, double bluebw)
nextgreenbw = greenbw;
nextbluebw = bluebw;
const auto func = [](gpointer data) -> gboolean {
static_cast<BlackWhite*>(data)->BWComputed_();
return FALSE;
const auto func =
[](BlackWhite* self) -> bool
{
self->BWComputed_();
return false;
};
idle_register.add(func, this);
idle_register.add<BlackWhite>(func, this, false);
}
bool BlackWhite::BWComputed_ ()

View File

@ -1452,63 +1452,63 @@ void ColorAppearance::setDefaults (const ProcParams* defParams, const ParamsEdit
void ColorAppearance::autoCamChanged (double ccam, double ccamout)
{
struct Data {
ColorAppearance *me;
ColorAppearance* me;
double ccam;
double ccamout;
};
const auto func = [](gpointer data) -> gboolean {
Data *d = static_cast<Data *>(data);
ColorAppearance *me = d->me;
me->disableListener();
me->degree->setValue(d->ccam);
me->degreeout->setValue(d->ccamout);
me->enableListener();
delete d;
return FALSE;
const auto func =
[](Data* data) -> bool
{
ColorAppearance* const self = data->me;
self->disableListener();
self->degree->setValue(data->ccam);
self->degreeout->setValue(data->ccamout);
self->enableListener();
return false;
};
idle_register.add(func, new Data { this, ccam, ccamout });
idle_register.add<Data>(func, new Data{this, ccam, ccamout}, true);
}
void ColorAppearance::adapCamChanged (double cadap)
{
struct Data {
ColorAppearance *me;
ColorAppearance* self;
double cadap;
};
const auto func = [](gpointer data) -> gboolean {
Data *d = static_cast<Data *>(data);
ColorAppearance *me = d->me;
me->disableListener();
me->adapscen->setValue(d->cadap);
me->enableListener();
delete d;
return FALSE;
const auto func =
[](Data* data) -> bool
{
ColorAppearance* const self = data->self;
self->disableListener();
self->adapscen->setValue(data->cadap);
self->enableListener();
return false;
};
idle_register.add(func, new Data { this, cadap });
idle_register.add<Data>(func, new Data{this, cadap}, true);
}
void ColorAppearance::ybCamChanged (int ybsc)
{
struct Data {
ColorAppearance *me;
ColorAppearance* self;
int ybsc;
};
const auto func = [](gpointer data) -> gboolean {
Data *d = static_cast<Data *>(data);
ColorAppearance *me = d->me;
me->disableListener();
me->ybscen->setValue(d->ybsc);
me->enableListener();
delete d;
return FALSE;
const auto func =
[](Data* data) -> bool
{
ColorAppearance* self = data->self;
self->disableListener();
self->ybscen->setValue(data->ybsc);
self->enableListener();
return false;
};
idle_register.add(func, new Data { this, ybsc });
idle_register.add<Data>(func, new Data{this, ybsc}, true);
}
void ColorAppearance::colorForValue (double valX, double valY, enum ColorCaller::ElemType elemType, int callerId, ColorCaller *caller)

View File

@ -690,23 +690,23 @@ void ColorToning::setAdjusterBehavior (bool splitAdd, bool satThresholdAdd, bool
void ColorToning::autoColorTonChanged(int satthres, int satprot)
{
struct Data {
ColorToning *me;
ColorToning *self;
int satthres;
int satprot;
};
const auto func = [](gpointer data) -> gboolean {
Data *d = static_cast<Data *>(data);
ColorToning *me = d->me;
me->disableListener();
me->satProtectionThreshold->setValue(d->satthres);
me->saturatedOpacity->setValue(d->satprot);
me->enableListener ();
delete d;
return FALSE;
const auto func =
[](Data* data) -> bool
{
ColorToning* const self = data->self;
self->disableListener();
self->satProtectionThreshold->setValue(data->satthres);
self->saturatedOpacity->setValue(data->satprot);
self->enableListener();
return false;
};
idle_register.add(func, new Data { this, satthres, satprot });
idle_register.add<Data>(func, new Data{this, satthres, satprot}, true);
}
void ColorToning::adjusterChanged (ThresholdAdjuster* a, double newBottom, double newTop)

View File

@ -38,18 +38,16 @@ public:
: crop(_crop), notify(_notify) {}
};
int refreshSpinsUI (void* data)
bool refreshSpinsUI(RefreshSpinHelper* rsh)
{
RefreshSpinHelper* rsh = static_cast<RefreshSpinHelper*>(data);
rsh->crop->refreshSpins (rsh->notify);
delete rsh;
return 0;
rsh->crop->refreshSpins(rsh->notify);
return false;
}
int notifyListenerUI (void* data)
bool notifyListenerUI(Crop* self)
{
static_cast<Crop*>(data)->notifyListener();
return 0;
self->notifyListener();
return false;
}
}
@ -515,16 +513,14 @@ void Crop::enabledChanged ()
void Crop::hFlipCrop ()
{
nx = maxw - nx - nw;
idle_register.add(refreshSpinsUI, new RefreshSpinHelper(this, false));
idle_register.add<RefreshSpinHelper>(refreshSpinsUI, new RefreshSpinHelper(this, false), true);
}
void Crop::vFlipCrop ()
{
ny = maxh - ny - nh;
idle_register.add(refreshSpinsUI, new RefreshSpinHelper(this, false));
idle_register.add<RefreshSpinHelper>(refreshSpinsUI, new RefreshSpinHelper(this, false), true);
}
void Crop::rotateCrop (int deg, bool hflip, bool vflip)
@ -564,7 +560,7 @@ void Crop::rotateCrop (int deg, bool hflip, bool vflip)
}
lastRotationDeg = deg;
idle_register.add(refreshSpinsUI, new RefreshSpinHelper(this, false));
idle_register.add<RefreshSpinHelper>(refreshSpinsUI, new RefreshSpinHelper(this, false), true);
}
void Crop::positionChanged ()
@ -578,7 +574,7 @@ void Crop::positionChanged ()
int W = nw;
int H = nh;
cropMoved (X, Y, W, H);
idle_register.add(notifyListenerUI, this);
idle_register.add<Crop>(notifyListenerUI, this, false);
}
void Crop::widthChanged ()
@ -591,7 +587,7 @@ void Crop::widthChanged ()
int W = (int)w->get_value ();
int H = nh;
cropWidth2Resized (X, Y, W, H);
idle_register.add(notifyListenerUI, this);
idle_register.add<Crop>(notifyListenerUI, this, false);
}
void Crop::heightChanged ()
@ -604,7 +600,7 @@ void Crop::heightChanged ()
int W = nw;
int H = (int)h->get_value ();
cropHeight2Resized (X, Y, W, H);
idle_register.add(notifyListenerUI, this);
idle_register.add<Crop>(notifyListenerUI, this, false);
}
// Fixed ratio toggle button
@ -656,7 +652,7 @@ void Crop::adjustCropToRatio()
}
// This will save the options
idle_register.add(refreshSpinsUI, new RefreshSpinHelper(this, true));
idle_register.add<RefreshSpinHelper>(refreshSpinsUI, new RefreshSpinHelper(this, true), true);
}
void Crop::refreshSize ()
@ -742,14 +738,14 @@ void Crop::sizeChanged(int x, int y, int ow, int oh)
y
};
const auto func = [](gpointer data) -> gboolean {
Params* const params = static_cast<Params*>(data);
const auto func =
[](Params* params) -> bool
{
params->crop->setDimensions(params->x, params->y);
delete params;
return FALSE;
return false;
};
idle_register.add(func, params);
idle_register.add<Params>(func, params, true);
}
bool Crop::refreshSpins (bool notify)
@ -813,7 +809,7 @@ void Crop::cropMoved (int &X, int &Y, int &W, int &H)
nw = W;
nh = H;
idle_register.add(refreshSpinsUI, new RefreshSpinHelper(this, false));
idle_register.add<RefreshSpinHelper>(refreshSpinsUI, new RefreshSpinHelper(this, false), true);
// Glib::signal_idle().connect (sigc::mem_fun(*this, &Crop::refreshSpins));
}
@ -857,7 +853,7 @@ void Crop::cropWidth1Resized (int &X, int &Y, int &W, int &H, float custom_ratio
nw = W;
nh = H;
idle_register.add(refreshSpinsUI, new RefreshSpinHelper(this, false));
idle_register.add<RefreshSpinHelper>(refreshSpinsUI, new RefreshSpinHelper(this, false), true);
}
void Crop::cropWidth2Resized (int &X, int &Y, int &W, int &H, float custom_ratio)
@ -897,7 +893,7 @@ void Crop::cropWidth2Resized (int &X, int &Y, int &W, int &H, float custom_ratio
nw = W;
nh = H;
idle_register.add(refreshSpinsUI, new RefreshSpinHelper(this, false));
idle_register.add<RefreshSpinHelper>(refreshSpinsUI, new RefreshSpinHelper(this, false), true);
}
void Crop::cropHeight1Resized (int &X, int &Y, int &W, int &H, float custom_ratio)
@ -940,7 +936,7 @@ void Crop::cropHeight1Resized (int &X, int &Y, int &W, int &H, float custom_rati
nw = W;
nh = H;
idle_register.add(refreshSpinsUI, new RefreshSpinHelper(this, false));
idle_register.add<RefreshSpinHelper>(refreshSpinsUI, new RefreshSpinHelper(this, false), true);
}
void Crop::cropHeight2Resized (int &X, int &Y, int &W, int &H, float custom_ratio)
@ -980,7 +976,7 @@ void Crop::cropHeight2Resized (int &X, int &Y, int &W, int &H, float custom_rati
nw = W;
nh = H;
idle_register.add(refreshSpinsUI, new RefreshSpinHelper(this, false));
idle_register.add<RefreshSpinHelper>(refreshSpinsUI, new RefreshSpinHelper(this, false), true);
}
void Crop::cropTopLeftResized (int &X, int &Y, int &W, int &H, float custom_ratio)
@ -1022,7 +1018,7 @@ void Crop::cropTopLeftResized (int &X, int &Y, int &W, int &H, float custom_rati
nw = W;
nh = H;
idle_register.add(refreshSpinsUI, new RefreshSpinHelper(this, false));
idle_register.add<RefreshSpinHelper>(refreshSpinsUI, new RefreshSpinHelper(this, false), true);
}
void Crop::cropTopRightResized (int &X, int &Y, int &W, int &H, float custom_ratio)
@ -1062,7 +1058,7 @@ void Crop::cropTopRightResized (int &X, int &Y, int &W, int &H, float custom_rat
nw = W;
nh = H;
idle_register.add(refreshSpinsUI, new RefreshSpinHelper(this, false));
idle_register.add<RefreshSpinHelper>(refreshSpinsUI, new RefreshSpinHelper(this, false), true);
}
void Crop::cropBottomLeftResized (int &X, int &Y, int &W, int &H, float custom_ratio)
@ -1102,7 +1098,7 @@ void Crop::cropBottomLeftResized (int &X, int &Y, int &W, int &H, float custom_r
nw = W;
nh = H;
idle_register.add(refreshSpinsUI, new RefreshSpinHelper(this, false));
idle_register.add<RefreshSpinHelper>(refreshSpinsUI, new RefreshSpinHelper(this, false), true);
}
void Crop::cropBottomRightResized (int &X, int &Y, int &W, int &H, float custom_ratio)
@ -1139,7 +1135,7 @@ void Crop::cropBottomRightResized (int &X, int &Y, int &W, int &H, float custom_
nw = W;
nh = H;
idle_register.add(refreshSpinsUI, new RefreshSpinHelper(this, false));
idle_register.add<RefreshSpinHelper>(refreshSpinsUI, new RefreshSpinHelper(this, false), true);
}
void Crop::cropInit (int &x, int &y, int &w, int &h)
@ -1253,12 +1249,12 @@ void Crop::cropResized (int &x, int &y, int& x2, int& y2)
nw = W;
nh = H;
idle_register.add(refreshSpinsUI, new RefreshSpinHelper(this, false));
idle_register.add<RefreshSpinHelper>(refreshSpinsUI, new RefreshSpinHelper(this, false), true);
}
void Crop::cropManipReady ()
{
idle_register.add(notifyListenerUI, this);
idle_register.add<Crop>(notifyListenerUI, this, false);
}
double Crop::getRatio () const

View File

@ -338,9 +338,9 @@ void CropHandler::setDetailedCrop(
bool expected = false;
if (redraw_needed.compare_exchange_strong(expected, true)) {
const auto func = [](gpointer data) -> gboolean {
CropHandler* const self = static_cast<CropHandler*>(data);
const auto func =
[](CropHandler* self) -> bool
{
self->cimg.lock ();
if (self->redraw_needed.exchange(false)) {
@ -350,7 +350,7 @@ void CropHandler::setDetailedCrop(
self->cropimg.clear();
self->cropimgtrue.clear();
self->cimg.unlock ();
return FALSE;
return false;
}
if (!self->cropimg.empty()) {
@ -398,10 +398,10 @@ void CropHandler::setDetailedCrop(
self->cimg.unlock();
}
return FALSE;
return false;
};
idle_register.add(func, this/*, G_PRIORITY_HIGH_IDLE*/);
idle_register.add<CropHandler>(func, this, false);
}
}

View File

@ -284,32 +284,32 @@ DirPyrDenoise::~DirPyrDenoise ()
void DirPyrDenoise::chromaChanged (double autchroma, double autred, double autblue)
{
struct Data {
DirPyrDenoise *me;
DirPyrDenoise* self;
double autchroma;
double autred;
double autblue;
};
const auto func = [](gpointer data) -> gboolean {
Data *d = static_cast<Data *>(data);
DirPyrDenoise *me = d->me;
me->disableListener();
me->chroma->setValue(d->autchroma);
me->redchro->setValue(d->autred);
me->bluechro->setValue(d->autblue);
me->enableListener();
delete d;
return FALSE;
const auto func =
[](Data* data) -> bool
{
DirPyrDenoise* const self = data->self;
self->disableListener();
self->chroma->setValue(data->autchroma);
self->redchro->setValue(data->autred);
self->bluechro->setValue(data->autblue);
self->enableListener();
return false;
};
idle_register.add(func, new Data { this, autchroma, autred, autblue });
idle_register.add<Data>(func, new Data{this, autchroma, autred, autblue}, true);
}
void DirPyrDenoise::noiseTilePrev (int tileX, int tileY, int prevX, int prevY, int sizeT, int sizeP)
{
if (!batchMode) {
struct Data {
DirPyrDenoise *me;
DirPyrDenoise* self;
int tileX;
int tileY;
int prevX;
@ -318,26 +318,26 @@ void DirPyrDenoise::noiseTilePrev (int tileX, int tileY, int prevX, int prevY, i
int sizeP;
};
const auto func = [](gpointer data) -> gboolean {
Data *d = static_cast<Data *>(data);
DirPyrDenoise *me = d->me;
me->TileLabels->set_text(
const auto func =
[](Data* data) -> bool
{
DirPyrDenoise* self = data->self;
self->TileLabels->set_text(
Glib::ustring::compose(M("TP_DIRPYRDENOISE_CHROMINANCE_PREVIEW_TILEINFO"),
Glib::ustring::format(std::fixed, std::setprecision(0), d->sizeT),
Glib::ustring::format(std::fixed, std::setprecision(0), d->tileX),
Glib::ustring::format(std::fixed, std::setprecision(0), d->tileY))
Glib::ustring::format(std::fixed, std::setprecision(0), data->sizeT),
Glib::ustring::format(std::fixed, std::setprecision(0), data->tileX),
Glib::ustring::format(std::fixed, std::setprecision(0), data->tileY))
);
me->PrevLabels->set_text(
self->PrevLabels->set_text(
Glib::ustring::compose(M("TP_DIRPYRDENOISE_CHROMINANCE_PREVIEW_INFO"),
Glib::ustring::format(std::fixed, std::setprecision(0), d->sizeP),
Glib::ustring::format(std::fixed, std::setprecision(0), d->prevX),
Glib::ustring::format(std::fixed, std::setprecision(0), d->prevY))
Glib::ustring::format(std::fixed, std::setprecision(0), data->sizeP),
Glib::ustring::format(std::fixed, std::setprecision(0), data->prevX),
Glib::ustring::format(std::fixed, std::setprecision(0), data->prevY))
);
delete d;
return FALSE;
return false;
};
idle_register.add(func, new Data { this, tileX, tileY, prevX, prevY, sizeT, sizeP });
idle_register.add<Data>(func, new Data{this, tileX, tileY, prevX, prevY, sizeT, sizeP}, true);
}
}
@ -345,20 +345,20 @@ void DirPyrDenoise::noiseChanged (double nresid, double highresid)
{
if (!batchMode) {
struct Data {
DirPyrDenoise *me;
DirPyrDenoise* self;
double nresid;
double highresid;
};
const auto func = [](gpointer data) -> gboolean {
Data *d = static_cast<Data *>(data);
DirPyrDenoise *me = d->me;
me->updateNoiseLabel(d->nresid, d->highresid);
delete d;
return FALSE;
const auto func =
[](Data* data) -> bool
{
DirPyrDenoise* const self = data->self;
self->updateNoiseLabel(data->nresid, data->highresid);
return false;
};
idle_register.add(func, new Data { this, nresid, highresid });
idle_register.add<Data>(func, new Data{this, nresid, highresid}, true);
}
}

View File

@ -45,10 +45,8 @@ struct spparams {
Glib::RefPtr<Gtk::CssProvider> cssProvider;
};
int setprogressStrUI ( void *p )
bool setprogressStrUI(spparams* s)
{
spparams *s = static_cast<spparams*> (p);
if ( ! s->str.empty() ) {
s->pProgress->set_text ( M (s->str) );
}
@ -67,8 +65,7 @@ int setprogressStrUI ( void *p )
}
}
delete s;
return FALSE;
return false;
}
@ -1192,7 +1189,7 @@ void EditorPanel::setProgress(double p)
spparams *s = new spparams;
s->val = p;
s->pProgress = progressLabel;
idle_register.add(setprogressStrUI, s);
idle_register.add<spparams>(setprogressStrUI, s, true);
}
void EditorPanel::setProgressStr(const Glib::ustring& str)
@ -1201,7 +1198,7 @@ void EditorPanel::setProgressStr(const Glib::ustring& str)
s->str = str;
s->val = -1;
s->pProgress = progressLabel;
idle_register.add(setprogressStrUI, s);
idle_register.add<spparams>(setprogressStrUI, s, true);
}
void EditorPanel::setProgressState(bool inProcessing)
@ -1217,9 +1214,9 @@ void EditorPanel::setProgressState(bool inProcessing)
p->inProcessing = inProcessing;
p->epih = epih;
const auto func = [] (gpointer data) -> gboolean {
spsparams* const p = static_cast<spsparams*> (data);
const auto func =
[](spsparams* p) -> bool
{
if (p->epih->destroyed)
{
if (p->epih->pending == 1) {
@ -1228,19 +1225,16 @@ void EditorPanel::setProgressState(bool inProcessing)
p->epih->pending--;
}
delete p;
return 0;
return false;
}
p->epih->epanel->refreshProcessingState (p->inProcessing);
p->epih->pending--;
delete p;
return FALSE;
return false;
};
idle_register.add (func, p);
idle_register.add<spsparams>(func, p, true);
}
void EditorPanel::error(const Glib::ustring& descr)
@ -1261,9 +1255,9 @@ void EditorPanel::error(const Glib::ustring& title, const Glib::ustring& descr)
p->title = title;
p->epih = epih;
const auto func = [] (gpointer data) -> gboolean {
errparams* const p = static_cast<errparams*> (data);
const auto func =
[](errparams* p) -> bool
{
if (p->epih->destroyed)
{
if (p->epih->pending == 1) {
@ -1272,19 +1266,16 @@ void EditorPanel::error(const Glib::ustring& title, const Glib::ustring& descr)
p->epih->pending--;
}
delete p;
return 0;
return false;
}
p->epih->epanel->displayError (p->title, p->descr);
p->epih->pending--;
delete p;
return FALSE;
return false;
};
idle_register.add (func, p);
idle_register.add<errparams>(func, p, true);
}
void EditorPanel::displayError(const Glib::ustring& title, const Glib::ustring& descr)

View File

@ -568,31 +568,30 @@ void FileBrowser::doubleClicked (ThumbBrowserEntryBase* entry)
void FileBrowser::addEntry (FileBrowserEntry* entry)
{
struct addparams {
FileBrowser *browser;
FileBrowserEntry *entry;
FileBrowser* self;
FileBrowserEntry* entry;
unsigned int session_id;
};
addparams* const ap = new addparams;
entry->setParent (this);
ap->browser = this;
ap->self = this;
ap->entry = entry;
ap->session_id = session_id();
const auto func = [](gpointer data) -> gboolean {
addparams* const ap = static_cast<addparams*>(data);
if (ap->session_id != ap->browser->session_id()) {
const auto func =
[](addparams* ap) -> bool
{
if (ap->session_id != ap->self->session_id()) {
delete ap->entry;
delete ap;
} else {
ap->browser->addEntry_(ap->entry);
delete ap;
ap->self->addEntry_(ap->entry);
}
return FALSE;
return false;
};
idle_register.add(func, ap);
idle_register.add<addparams>(func, ap, true);
}
void FileBrowser::addEntry_ (FileBrowserEntry* entry)
@ -1935,13 +1934,14 @@ void FileBrowser::_thumbRearrangementNeeded ()
void FileBrowser::thumbRearrangementNeeded ()
{
const auto func = [](gpointer data) -> gboolean {
static_cast<FileBrowser*>(data)->_thumbRearrangementNeeded();
return FALSE;
const auto func =
[](FileBrowser* self) -> bool
{
self->_thumbRearrangementNeeded();
return false;
};
idle_register.add(func, this);
idle_register.add<FileBrowser>(func, this, false);
}
void FileBrowser::selectionChanged ()

View File

@ -233,8 +233,9 @@ void FileBrowserEntry::updateImage(rtengine::IImage8* img, double scale, const r
const gint priority = G_PRIORITY_LOW;
const auto func = [](gpointer data) -> gboolean {
tiupdate* const params = static_cast<tiupdate*>(data);
const auto func =
[](tiupdate* params) -> bool
{
FileBrowserEntryIdleHelper* const feih = params->feih;
if (feih->destroyed) {
@ -245,19 +246,16 @@ void FileBrowserEntry::updateImage(rtengine::IImage8* img, double scale, const r
}
params->img->free ();
delete params;
return 0;
return false;
}
feih->fbentry->_updateImage (params->img, params->scale, params->cropParams);
feih->pending--;
delete params;
return FALSE;
return false;
};
idle_register.add(func, param, priority);
idle_register.add<tiupdate>(func, param, true, priority);
}
void FileBrowserEntry::_updateImage(rtengine::IImage8* img, double s, const rtengine::procparams::CropParams& cropParams)

View File

@ -873,13 +873,14 @@ void FileCatalog::previewsFinished (int dir_id)
currentEFS = dirEFS;
}
const auto func = [](gpointer data) -> gboolean {
static_cast<FileCatalog*>(data)->previewsFinishedUI();
return FALSE;
const auto func =
[](FileCatalog* self) -> bool
{
self->previewsFinishedUI();
return false;
};
idle_register.add(func, this);
idle_register.add<FileCatalog>(func, this, false);
}
void FileCatalog::setEnabled (bool e)
@ -941,24 +942,22 @@ struct FCOIParams {
std::vector<Thumbnail*> tmb;
};
int openRequestedUI (void* p)
bool openRequestedUI(FCOIParams* params)
{
FCOIParams* params = static_cast<FCOIParams*>(p);
params->catalog->_openImage (params->tmb);
delete params;
return 0;
return false;
}
void FileCatalog::filterApplied()
{
const auto func = [](gpointer data) -> gboolean {
static_cast<FileCatalog*>(data)->_refreshProgressBar();
return FALSE;
const auto func =
[](FileCatalog* self) -> bool
{
self->_refreshProgressBar();
return false;
};
idle_register.add(func, this);
idle_register.add<FileCatalog>(func, this, false);
}
void FileCatalog::openRequested(const std::vector<Thumbnail*>& tmb)
@ -971,7 +970,7 @@ void FileCatalog::openRequested(const std::vector<Thumbnail*>& tmb)
tmb[i]->increaseRef ();
}
idle_register.add(openRequestedUI, params);
idle_register.add<FCOIParams>(openRequestedUI, params, true);
}
void FileCatalog::deleteRequested(const std::vector<FileBrowserEntry*>& tbe, bool inclBatchProcessed)
@ -1903,7 +1902,7 @@ void FileCatalog::addAndOpenFile (const Glib::ustring& fname)
params->catalog = this;
params->tmb.push_back (tmb);
tmb->increaseRef ();
idle_register.add(openRequestedUI, params);
idle_register.add<FCOIParams>(openRequestedUI, params, true);
} catch(Gio::Error&) {}
}

View File

@ -139,12 +139,14 @@ FilePanel::FilePanel () : parent(nullptr), error(0)
fileCatalog->setFileSelectionListener (this);
const auto func = [](gpointer data) -> gboolean {
static_cast<FilePanel*>(data)->init();
return FALSE;
const auto func =
[](FilePanel* self) -> bool
{
self->init();
return false;
};
idle_register.add(func, this);
idle_register.add<FilePanel>(func, this, false);
show_all ();
}

View File

@ -412,18 +412,19 @@ void FlatField::setShortcutPath(const Glib::ustring& path)
void FlatField::flatFieldAutoClipValueChanged(int n)
{
struct Data {
FlatField *me;
FlatField* self;
int n;
};
const auto func = [](gpointer data) -> gboolean {
Data *d = static_cast<Data *>(data);
FlatField *me = d->me;
me->disableListener();
me->flatFieldClipControl->setValue (d->n);
me->enableListener();
delete d;
return FALSE;
const auto func =
[](Data* data) -> bool
{
FlatField* const self = data->self;
self->disableListener();
self->flatFieldClipControl->setValue (data->n);
self->enableListener();
return false;
};
idle_register.add(func, new Data { this, n });
idle_register.add<Data>(func, new Data{this, n}, true);
}

View File

@ -43,39 +43,14 @@ IdleRegister::~IdleRegister()
destroy();
}
void IdleRegister::add(GSourceFunc function, gpointer data, gint priority)
{
const auto dispatch = [](gpointer data) -> gboolean {
DataWrapper* const data_wrapper = static_cast<DataWrapper*>(data);
if (!data_wrapper->function(data_wrapper->data)) {
data_wrapper->self->mutex.lock();
data_wrapper->self->ids.erase(data_wrapper);
data_wrapper->self->mutex.unlock();
delete data_wrapper;
return FALSE;
}
return TRUE;
};
DataWrapper* const data_wrapper = new DataWrapper{
this,
function,
data
};
mutex.lock();
ids[data_wrapper] = gdk_threads_add_idle_full(priority, dispatch, data_wrapper, nullptr);
mutex.unlock();
}
void IdleRegister::destroy()
{
mutex.lock();
for (const auto& id : ids) {
g_source_remove(id.second);
if (id.first->deleter) {
id.first->deleter(id.first->data);
}
delete id.first;
}
ids.clear();

View File

@ -50,7 +50,54 @@ class IdleRegister final :
public:
~IdleRegister();
void add(GSourceFunc function, gpointer data, gint priority = G_PRIORITY_DEFAULT_IDLE);
template<typename DATA>
void add(bool (*function)(DATA*), DATA* data, bool delete_data, gint priority = G_PRIORITY_DEFAULT_IDLE)
{
const auto dispatch =
[](gpointer data) -> gboolean
{
DataWrapper* const data_wrapper = static_cast<DataWrapper*>(data);
// This is safe as per https://en.cppreference.com/w/cpp/language/reinterpret_cast item 7)
if (!reinterpret_cast<bool (*)(DATA*)>(data_wrapper->function)(static_cast<DATA*>(data_wrapper->data))) {
data_wrapper->self->mutex.lock();
data_wrapper->self->ids.erase(data_wrapper);
data_wrapper->self->mutex.unlock();
if (data_wrapper->deleter) {
data_wrapper->deleter(data_wrapper->data);
}
delete data_wrapper;
return FALSE;
}
return TRUE;
};
DataWrapper* const data_wrapper = new DataWrapper{
this,
reinterpret_cast<GSourceFunc>(function),
data,
[delete_data]() -> GSourceFunc
{
if (delete_data) {
return
[](gpointer data) -> gboolean
{
delete static_cast<DATA*>(data);
return TRUE;
};
}
return nullptr;
}()
};
mutex.lock();
ids[data_wrapper] = gdk_threads_add_idle_full(priority, dispatch, data_wrapper, nullptr);
mutex.unlock();
}
void destroy();
private:
@ -58,6 +105,7 @@ private:
IdleRegister* const self;
GSourceFunc function;
gpointer data;
GSourceFunc deleter;
};
std::map<const DataWrapper*, guint> ids;

View File

@ -562,9 +562,9 @@ void HistogramRGBArea::update (int valh, int rh, int gh, int bh)
harih->pending++;
const auto func = [](gpointer data) -> gboolean {
HistogramRGBAreaIdleHelper* const harih = static_cast<HistogramRGBAreaIdleHelper*>(data);
const auto func =
[](HistogramRGBAreaIdleHelper* harih) -> bool
{
if (harih->destroyed) {
if (harih->pending == 1) {
delete harih;
@ -572,7 +572,7 @@ void HistogramRGBArea::update (int valh, int rh, int gh, int bh)
harih->pending--;
}
return 0;
return false;
}
harih->harea->updateBackBuffer(-1, -1, -1);
@ -580,10 +580,10 @@ void HistogramRGBArea::update (int valh, int rh, int gh, int bh)
harih->pending--;
return FALSE;
return false;
};
idle_register.add(func, harih);
idle_register.add<HistogramRGBAreaIdleHelper>(func, harih, false);
}
void HistogramRGBArea::updateOptions (bool r, bool g, bool b, bool l, bool c, bool raw, bool bar)
@ -761,9 +761,9 @@ void HistogramArea::update(
haih->pending++;
// Can be done outside of the GUI thread
const auto func = [](gpointer data) -> gboolean {
HistogramAreaIdleHelper* const haih = static_cast<HistogramAreaIdleHelper*>(data);
const auto func =
[](HistogramAreaIdleHelper* haih) -> bool
{
if (haih->destroyed) {
if (haih->pending == 1) {
delete haih;
@ -771,7 +771,7 @@ void HistogramArea::update(
haih->pending--;
}
return 0;
return false;
}
haih->harea->setDirty (true);
@ -780,10 +780,10 @@ void HistogramArea::update(
haih->pending--;
return FALSE;
return false;
};
idle_register.add(func, haih);
idle_register.add<HistogramAreaIdleHelper>(func, haih, false);
}
void HistogramArea::updateBackBuffer ()

View File

@ -1516,9 +1516,9 @@ void MyDiagonalCurve::updateBackgroundHistogram (LUTu & hist)
mcih->pending++;
const auto func = [](gpointer data) -> gboolean {
MyCurveIdleHelper* const mcih = static_cast<MyCurveIdleHelper*>(data);
const auto func =
[](MyCurveIdleHelper* mcih) -> bool
{
if (mcih->destroyed) {
if (mcih->pending == 1) {
delete mcih;
@ -1526,7 +1526,7 @@ void MyDiagonalCurve::updateBackgroundHistogram (LUTu & hist)
mcih->pending--;
}
return 0;
return false;
}
mcih->clearPixmap ();
@ -1534,10 +1534,10 @@ void MyDiagonalCurve::updateBackgroundHistogram (LUTu & hist)
mcih->pending--;
return FALSE;
return false;
};
idle_register.add(func, mcih);
idle_register.add<MyCurveIdleHelper>(func, mcih, false);
}
void MyDiagonalCurve::reset(const std::vector<double> &resetCurve, double identityValue)

View File

@ -67,8 +67,9 @@ void PreviewHandler::setImage(rtengine::IImage8* i, double scale, const rtengine
iap->scale = scale;
iap->cp = cp;
const auto func = [](gpointer data) -> gboolean {
iaimgpar* const iap = static_cast<iaimgpar*>(data);
const auto func =
[](iaimgpar* iap) -> bool
{
PreviewHandlerIdleHelper* const pih = iap->pih;
if (pih->destroyed) {
@ -78,9 +79,7 @@ void PreviewHandler::setImage(rtengine::IImage8* i, double scale, const rtengine
pih->pending--;
}
delete iap;
return FALSE;
return false;
}
if (pih->phandler->image) {
@ -95,12 +94,11 @@ void PreviewHandler::setImage(rtengine::IImage8* i, double scale, const rtengine
pih->phandler->cropParams = iap->cp;
pih->phandler->previewScale = iap->scale;
pih->pending--;
delete iap;
return FALSE;
return false;
};
idle_register.add(func, iap);
idle_register.add<iaimgpar>(func, iap, true);
}
@ -112,9 +110,10 @@ void PreviewHandler::delImage(IImage8* i)
iap->image = i;
iap->pih = pih;
const auto func = [](gpointer data) -> gboolean {
iaimgpar* iap = static_cast<iaimgpar*>(data);
PreviewHandlerIdleHelper* pih = iap->pih;
const auto func =
[](iaimgpar* iap) -> bool
{
PreviewHandlerIdleHelper* const pih = iap->pih;
if (pih->destroyed) {
if (pih->pending == 1) {
@ -123,9 +122,7 @@ void PreviewHandler::delImage(IImage8* i)
pih->pending--;
}
delete iap;
return FALSE;
return false;
}
if (pih->phandler->image) {
@ -141,12 +138,11 @@ void PreviewHandler::delImage(IImage8* i)
pih->phandler->previewImgMutex.unlock ();
pih->pending--;
delete iap;
return FALSE;
return false;
};
idle_register.add(func, iap);
idle_register.add<iaimgpar>(func, iap, true);
}
void PreviewHandler::imageReady(const rtengine::procparams::CropParams& cp)
@ -156,9 +152,10 @@ void PreviewHandler::imageReady(const rtengine::procparams::CropParams& cp)
iap->pih = pih;
iap->cp = cp;
const auto func = [](gpointer data) -> gboolean {
iaimgpar* const iap = static_cast<iaimgpar*>(data);
PreviewHandlerIdleHelper* pih = iap->pih;
const auto func =
[](iaimgpar* iap) -> bool
{
PreviewHandlerIdleHelper* const pih = iap->pih;
if (pih->destroyed) {
if (pih->pending == 1) {
@ -167,9 +164,7 @@ void PreviewHandler::imageReady(const rtengine::procparams::CropParams& cp)
pih->pending--;
}
delete iap;
return FALSE;
return false;
}
pih->phandler->previewImgMutex.lock ();
@ -178,12 +173,11 @@ void PreviewHandler::imageReady(const rtengine::procparams::CropParams& cp)
pih->phandler->cropParams = iap->cp;
pih->phandler->previewImageChanged ();
pih->pending--;
delete iap;
return FALSE;
return false;
};
idle_register.add(func, iap);
idle_register.add<iaimgpar>(func, iap, true);
}
Glib::RefPtr<Gdk::Pixbuf> PreviewHandler::getRoughImage (int x, int y, int w, int h, double zoom)

View File

@ -366,9 +366,9 @@ void Resize::sizeChanged(int mw, int mh, int ow, int oh)
void Resize::setDimensions ()
{
const auto func = [](gpointer data) -> gboolean {
Resize* const self = static_cast<Resize*>(data);
const auto func =
[](Resize* self) -> bool
{
self->wconn.block(true);
self->hconn.block(true);
self->scale->block(true);
@ -432,10 +432,10 @@ void Resize::setDimensions ()
self->wconn.block(false);
self->hconn.block(false);
return FALSE;
return false;
};
idle_register.add(func, this);
idle_register.add<Resize>(func, this, false);
}
void Resize::fitBoxScale()

View File

@ -673,14 +673,16 @@ void Retinex::minmaxChanged (double cdma, double cdmin, double mini, double maxi
nextminT = Tmin;
nextmaxT = Tmax;
const auto func = [] (gpointer data) -> gboolean {
const auto func =
[](Retinex* self) -> bool
{
GThreadLock lock; // All GUI access from idle_add callbacks or separate thread HAVE to be protected
static_cast<Retinex*> (data)->minmaxComputed_();
return FALSE;
// FIXME: The above can't be true?!
self->minmaxComputed_();
return false;
};
idle_register.add (func, this);
idle_register.add<Retinex>(func, this, false);
}
bool Retinex::minmaxComputed_ ()

View File

@ -1013,13 +1013,14 @@ void ToneCurve::autoExpChanged(double expcomp, int bright, int contr, int black,
nextHlcomprthresh = hlcomprthresh;
nextHLRecons = hlrecons;
const auto func = [](gpointer data) -> gboolean {
static_cast<ToneCurve*>(data)->autoExpComputed_();
return FALSE;
const auto func =
[](ToneCurve* self) -> bool
{
self->autoExpComputed_();
return false;
};
idle_register.add(func, this);
idle_register.add<ToneCurve>(func, this, false);
}
void ToneCurve::autoMatchedToneCurveChanged(rtengine::procparams::ToneCurveParams::TcMode curveMode, const std::vector<double>& curve)
@ -1027,11 +1028,12 @@ void ToneCurve::autoMatchedToneCurveChanged(rtengine::procparams::ToneCurveParam
nextToneCurveMode = curveMode;
nextToneCurve = curve;
const auto func = [](gpointer data) -> gboolean {
static_cast<ToneCurve*>(data)->histmatchingComputed();
return FALSE;
const auto func =
[](ToneCurve* self) -> bool
{
self->histmatchingComputed();
return false;
};
idle_register.add(func, this);
idle_register.add<ToneCurve>(func, this, false);
}

View File

@ -263,9 +263,9 @@ void ToolPanelCoordinator::imageTypeChanged (bool isRaw, bool isBayer, bool isXt
{
if (isRaw) {
if (isBayer) {
const auto func = [](gpointer data) -> gboolean {
ToolPanelCoordinator* const self = static_cast<ToolPanelCoordinator*>(data);
const auto func =
[](ToolPanelCoordinator* self) -> bool
{
self->rawPanelSW->set_sensitive (true);
self->sensorxtrans->FoldableToolPanel::hide();
self->sensorbayer->FoldableToolPanel::show();
@ -273,14 +273,14 @@ void ToolPanelCoordinator::imageTypeChanged (bool isRaw, bool isBayer, bool isXt
self->flatfield->FoldableToolPanel::show();
self->retinex->FoldableToolPanel::setGrayedOut(false);
return FALSE;
return false;
};
idle_register.add(func, this);
idle_register.add<ToolPanelCoordinator>(func, this, false);
}
else if (isXtrans) {
const auto func = [](gpointer data) -> gboolean {
ToolPanelCoordinator* const self = static_cast<ToolPanelCoordinator*>(data);
const auto func =
[](ToolPanelCoordinator* self) -> bool
{
self->rawPanelSW->set_sensitive (true);
self->sensorxtrans->FoldableToolPanel::show();
self->sensorbayer->FoldableToolPanel::hide();
@ -288,14 +288,14 @@ void ToolPanelCoordinator::imageTypeChanged (bool isRaw, bool isBayer, bool isXt
self->flatfield->FoldableToolPanel::show();
self->retinex->FoldableToolPanel::setGrayedOut(false);
return FALSE;
return false;
};
idle_register.add(func, this);
idle_register.add<ToolPanelCoordinator>(func, this, false);
}
else if (isMono) {
const auto func = [](gpointer data) -> gboolean {
ToolPanelCoordinator* const self = static_cast<ToolPanelCoordinator*>(data);
const auto func =
[](ToolPanelCoordinator* self) -> bool
{
self->rawPanelSW->set_sensitive (true);
self->sensorbayer->FoldableToolPanel::hide();
self->sensorxtrans->FoldableToolPanel::hide();
@ -303,13 +303,13 @@ void ToolPanelCoordinator::imageTypeChanged (bool isRaw, bool isBayer, bool isXt
self->flatfield->FoldableToolPanel::show();
self->retinex->FoldableToolPanel::setGrayedOut(false);
return FALSE;
return false;
};
idle_register.add(func, this);
idle_register.add<ToolPanelCoordinator>(func, this, false);
} else {
const auto func = [](gpointer data) -> gboolean {
ToolPanelCoordinator* const self = static_cast<ToolPanelCoordinator*>(data);
const auto func =
[](ToolPanelCoordinator* self) -> bool
{
self->rawPanelSW->set_sensitive (true);
self->sensorbayer->FoldableToolPanel::hide();
self->sensorxtrans->FoldableToolPanel::hide();
@ -317,20 +317,20 @@ void ToolPanelCoordinator::imageTypeChanged (bool isRaw, bool isBayer, bool isXt
self->flatfield->FoldableToolPanel::hide();
self->retinex->FoldableToolPanel::setGrayedOut(false);
return FALSE;
return false;
};
idle_register.add(func, this);
idle_register.add<ToolPanelCoordinator>(func, this, false);
}
} else {
const auto func = [](gpointer data) -> gboolean {
ToolPanelCoordinator* const self = static_cast<ToolPanelCoordinator*>(data);
const auto func =
[](ToolPanelCoordinator* self) -> bool
{
self->rawPanelSW->set_sensitive (false);
self->retinex->FoldableToolPanel::setGrayedOut(true);
return FALSE;
return false;
};
idle_register.add(func, this);
idle_register.add<ToolPanelCoordinator>(func, this, false);
}
}

View File

@ -888,22 +888,22 @@ void Wavelet::wavChanged (double nlevel)
{
if (!batchMode) {
struct Data {
Wavelet *me;
Wavelet *self;
double nlevel;
};
const auto func = [](gpointer data) -> gboolean {
Data *d = static_cast<Data *>(data);
Wavelet *me = d->me;
me->wavLabels->set_text(
const auto func =
[](Data* data) -> bool
{
Wavelet* self = data->self;
self->wavLabels->set_text(
Glib::ustring::compose(M("TP_WAVELET_LEVLABEL"),
Glib::ustring::format(std::fixed, std::setprecision(0), d->nlevel))
Glib::ustring::format(std::fixed, std::setprecision(0), data->nlevel))
);
delete d;
return FALSE;
return false;
};
idle_register.add(func, new Data { this, nlevel });
idle_register.add<Data>(func, new Data{this, nlevel}, true);
}
}

View File

@ -915,11 +915,12 @@ void WhiteBalance::WBChanged(double temperature, double greenVal)
double green_val;
};
const auto func = [](gpointer data) -> gboolean {
WhiteBalance* const self = static_cast<WhiteBalance*>(static_cast<Data*>(data)->self);
const double temperature = static_cast<Data*>(data)->temperature;
const double green_val = static_cast<Data*>(data)->green_val;
delete static_cast<Data*>(data);
const auto func =
[](Data* data) -> bool
{
WhiteBalance* const self = static_cast<WhiteBalance*>(data->self);
const double temperature = data->temperature;
const double green_val = data->green_val;
self->disableListener();
self->setEnabled(true);
@ -929,8 +930,8 @@ void WhiteBalance::WBChanged(double temperature, double greenVal)
self->green->setDefault(green_val);
self->enableListener();
return FALSE;
return false;
};
idle_register.add(func, new Data{this, temperature, greenVal});
idle_register.add<Data>(func, new Data{this, temperature, greenVal}, true);
}

View File

@ -255,18 +255,19 @@ void XTransProcess::checkBoxToggled (CheckBox* c, CheckValue newval)
void XTransProcess::autoContrastChanged (double autoContrast)
{
struct Data {
XTransProcess *me;
XTransProcess* self;
double autoContrast;
};
const auto func = [](gpointer data) -> gboolean {
Data *d = static_cast<Data *>(data);
XTransProcess *me = d->me;
me->disableListener();
me->dualDemosaicContrast->setValue(d->autoContrast);
me->enableListener();
delete d;
return FALSE;
const auto func =
[](Data* data) -> bool
{
XTransProcess* self = data->self;
self->disableListener();
self->dualDemosaicContrast->setValue(data->autoContrast);
self->enableListener();
return false;
};
idle_register.add(func, new Data { this, autoContrast });
idle_register.add<Data>(func, new Data{this, autoContrast}, true);
}