1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
|
/*
* This file is part of Chalk
*
* Copyright (c) 2005 Bart Coppens <kde@bartcoppens.be>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include <tqthread.h>
#include <tqapplication.h>
#include <tqevent.h>
#include "kis_accumulating_producer.h"
static const int EmitCompletedType = TQEvent::User + 1;
/**
* The threaded producer definition in c++ file because this is really an internal affair.
* Note that since we _know_ that we'll only have a single instance of it running, at most,
* we don't care too much about locking and synchronization
**/
class KisAccumulatingHistogramProducer::ThreadedProducer : public TQThread {
KisAccumulatingHistogramProducer* m_source;
bool m_stop;
protected:
virtual void run();
public:
ThreadedProducer(KisAccumulatingHistogramProducer* source)
: m_source(source), m_stop(false) {}
void cancel() { m_stop = true; }
};
KisAccumulatingHistogramProducer::KisAccumulatingHistogramProducer(KisCachedHistogramObserver::Producers* source)
: KisBasicHistogramProducer(
KisID("ACCHISTO", ""),
source->at(0)->channels().count(),
source->at(0)->numberOfBins(),
0),
m_source(source)
{
m_thread = new ThreadedProducer(this);
}
KisAccumulatingHistogramProducer::~KisAccumulatingHistogramProducer() {
m_thread->cancel();
m_thread->wait();
delete m_thread;
}
void KisAccumulatingHistogramProducer::addRegionsToBinAsync() {
m_thread->cancel();
m_thread->wait();
clear();
m_thread->start();
}
void KisAccumulatingHistogramProducer::ThreadedProducer::run() {
m_stop = false;
uint count = m_source->m_source->count(); // Talk about bad naming schemes...
KisCachedHistogramObserver::Producers* source = m_source->m_source;
TQValueVector<vBins>& bins = m_source->m_bins;
int channels = m_source->m_channels;
int nrOfBins = m_source->m_nrOfBins;
for (uint i = 0; i < count && !m_stop; i++) {
KisHistogramProducer* p = source->at(i);
m_source->m_count += p->count();
for (int j = 0; j < channels && !m_stop; j++) {
for (int k = 0; k < nrOfBins; k++) {
bins.at(j).at(k) += p->getBinAt(j, k);
}
}
}
if (!m_stop) {
// This function is thread-safe; and it takes ownership of the event
TQApplication::postEvent(m_source, new TQCustomEvent(EmitCompletedType));
}
}
void KisAccumulatingHistogramProducer::customEvent(TQCustomEvent* e) {
if (e->type() == EmitCompletedType) {
emit completed();
}
}
#include "kis_accumulating_producer.moc"
|