3 #include "DisplayController.h"
4 #include "BaseController_p.h"
5 #include "helpers/SyncQueues.h"
6 #include "parameters/Scope.h"
7 #include "helpers/ScopeMultiImage.h"
8 #include "helpers/ScopeMultiImageResonanceSW.h"
10 #include "gui/ChannelFrame.h"
11 #include "gui/HistogramFrame.h"
12 #include "ScopeLogger.h"
30 std::array<std::vector<gui::CChannelFrame* const>, SCOPE_NAREAS>
channelframes;
36 std::array<std::vector<gui::CHistogramFrame* const>, SCOPE_NAREAS>
histogramframes;
54 DBOUT(L
"DisplayController::Impl::Run beginning\n");
56 SCOPE_MULTIIMAGEPTR_T current_frame;
57 ControllerReturnStatus returnstatus(ControllerReturnStatus::none);
58 std::array<uint32_t, SCOPE_NAREAS> framecounts;
59 std::fill(std::begin(framecounts), std::end(framecounts), 0);
62 std::array<uint32_t, SCOPE_NAREAS> requested_frames;
65 std::array<std::unique_lock<std::mutex>, SCOPE_NAREAS> channelframes_locks;
66 std::array<std::unique_lock<std::mutex>, SCOPE_NAREAS> histogramframes_locks;
67 for ( uint32_t a = 0 ; a < SCOPE_NAREAS ; a++ ) {
69 channelframes_locks[a] = std::unique_lock<std::mutex>(channelframes_mutexe[a],std::defer_lock);
70 histogramframes_locks[a] = std::unique_lock<std::mutex>(histogramframes_mutexe[a],std::defer_lock);
77 while ( !sc->
IsSet() ) {
82 if ( msg.tag == ScopeMessageTag::abort ) {
83 returnstatus = ControllerReturnStatus::stopped;
87 current_frame = msg.
cargo;
88 area = current_frame->Area();
91 if ( current_frame->IsCompleteFrame() && current_frame->IsCompleteAvg() ) {
93 DBOUT(L
"DisplayController framecount area " << area << L
": " << framecounts[area]);
97 channelframes_locks[area].lock();
98 for (
auto cframe : channelframes[area] )
99 cframe->LayOverAndRender(current_frame);
100 channelframes_locks[area].unlock();
104 if ( current_frame->IsCompleteFrame() ) {
105 histogramframes_locks[area].lock();
106 for (
auto hframe : histogramframes[area] )
107 hframe->HistoGramAndRender(current_frame);
108 histogramframes_locks[area].unlock();
112 if ( (requested_mode == DaqModeHelper::nframes)
113 && (std::equal(std::begin(requested_frames), std::end(requested_frames), std::begin(framecounts))) ) {
116 returnstatus = ControllerReturnStatus::finished;
117 DBOUT(L
"DisplayController::Impl::Run - all requested frames from all areas processed\n");
122 returnstatus = ControllerReturnStatus(returnstatus || ControllerReturnStatus::stopped);
125 DBOUT(L
"DisplayController::Impl::Run ended\n");
131 for ( uint32_t a = 0 ; a < SCOPE_NAREAS ; a++ ) {
132 std::lock_guard<std::mutex> lockc(channelframes_mutexe[a]);
133 for(
auto cframe : channelframes[a] )
134 cframe->UpdateStatus(_rs);
135 std::lock_guard<std::mutex> lockh(histogramframes_mutexe[a]);
136 for(
auto hframe : histogramframes[a] )
137 hframe->UpdateStatus(_rs);
145 , input_queue(_iqueue) {
146 DBOUT(L
"DisplayController::Impl::Impl");
151 DBOUT(L
"DisplayController::Impl::~Impl");
170 input_queue->
Clear();
177 void SetHistogramLimits(
const uint32_t& _area,
const uint32_t& _channel,
const uint16_t& _lower,
const uint16_t& _upper) {
178 std::lock_guard<std::mutex> lock(channelframes_mutexe[_area]);
179 for (
auto cframe : channelframes[_area] )
180 cframe->SetHistogramLimits(_channel, _lower, _upper);
186 uint32_t area = _cframe->
Area();
187 std::lock_guard<std::mutex> lock(channelframes_mutexe[area]);
188 channelframes[area].push_back(_cframe);
196 uint32_t area = _cframe->
Area();
197 std::lock_guard<std::mutex> lock(channelframes_mutexe[area]);
198 std::vector<gui::CChannelFrame* const>::iterator found
199 = std::find_if(std::begin(channelframes[area]), std::end(channelframes[area]), [&](
const gui::CChannelFrame*
const f)
200 {
return f->m_hWnd == _cframe->m_hWnd; } );
201 if ( found == std::end(channelframes[area]) )
202 throw std::exception(
"DisplayController::Impl::DetachChannelFrame no match");
204 channelframes[area].erase(found);
210 uint32_t area = _hframe->
Area();
211 std::lock_guard<std::mutex> lock(histogramframes_mutexe[area]);
212 histogramframes[area].push_back(_hframe);
219 std::lock_guard<std::mutex> lock(histogramframes_mutexe[_area]);
220 return (histogramframes[_area].size() > 0);
227 uint32_t area = _hframe->
Area();
228 std::lock_guard<std::mutex> lock(histogramframes_mutexe[area]);
229 std::vector<gui::CHistogramFrame* const>::iterator found
230 = std::find_if(std::begin(histogramframes[area]), std::end(histogramframes[area]), [&](
const gui::CHistogramFrame*
const f)
231 {
return f->m_hWnd == _hframe->m_hWnd; } );
232 if ( found == std::end(histogramframes[area]) )
233 throw std::exception(
"DisplayController::Impl::DetachHistogramFrame no match");
235 histogramframes[area].erase(found);
242 for ( uint32_t a = 0 ; a < SCOPE_NAREAS ; a++ ) {
244 std::lock_guard<std::mutex> lock(histogramframes_mutexe[a]);
245 for (
const auto& h : histogramframes[a] ) {
246 wndcoll.
AddWindow(L
"CHistogramFrame", a, h->m_hWnd);
251 std::lock_guard<std::mutex> lock(channelframes_mutexe[a]);
252 for (
const auto& c : channelframes[a] ) {
253 wndcoll.
AddWindow(L
"CChannelFrame", a, c->m_hWnd);
std::array< std::mutex, SCOPE_NAREAS > histogramframes_mutexe
Mutex to protect access to that vector.
Parameters for a whole area (includes a daq and a fpu)
parameters::Scope parameters
the Controller's own set of ScopeParameters
ScopeLogger scope_logger
a ScopeLogger kept handy here
void AttachFrame(gui::CChannelFrame *const _cframe)
Attaches a CChannelFrame as observer to the DisplayController.
Thread-safe lock-free bool to signal a requested stop to the worker function currently executed in th...
The master parameters class.
std::array< std::unique_ptr< Area >, SCOPE_NAREAS > areas
holds AreaParameters for all areas.
void Clear()
Clears the queue.
void StopOne(const uint32_t &_a) override
We need to override here.
void UpdateStatus(const RunState &_rs)
Updates the statusstr and send RunUpdateStatusbar to the Active object.
void AttachFrame(gui::CHistogramFrame *const _hframe)
Attaches a CHistogramFrame as observer to the DisplayController.
std::array< std::mutex, SCOPE_NAREAS > channelframes_mutexe
Mutex to protect access to that vector.
bool HistogramAlreadyAttached(const uint32_t &_area) const
parameters::WindowCollection GetWindowCollection() const
Adds frames to a WindowCollection.
Impl(SynchronizedQueue< ScopeMessage< SCOPE_MULTIIMAGEPTR_T >> *const _iqueue, const parameters::Scope _parameters)
Connects queue and gets parameters.
Base class for all Scope datatypes here, provides a uniform interface (and saves typing...).
void Enqueue(const T &elem)
Enqueues an element and notifies one waiting operation that queue is not empty.
Manages the display of images.
void AddWindow(const std::wstring &_type, const uint32_t &_area, HWND _hwnd)
Add a window to the collection.
The implementation class of the DisplayController.
A logger class to log various messages and user comments.
ScopeValue< DaqMode > requested_mode
requested acquisition mode (see DaqModeHelper)
Impl operator=(const Impl &i)
disable assignment
ControllerReturnStatus Run(StopCondition *const sc, const uint32_t &_area) override
Main function for managing display.
In here all declarations for all kinds of datatypes Scope needs.
void ResolutionChange(const parameters::Area &_ap)
Go through all CChannelFrames and request resize to cope with new image size.
virtual ControllerReturnStatus WaitForAll(const int32_t &_wait_time)
Wait for the futures of all async worker functions.
virtual void StopAll()
Request all async worker function to stop.
virtual void StopOne(const uint32_t &_a)
Request one async worker function to stop by settings its StopCondition to true.
#define DBOUT(s)
A debug output to the debug console.
Manages the display of histograms.
std::array< std::vector< gui::CChannelFrame *const >, SCOPE_NAREAS > channelframes
Vector of CChannelFrame observers.
A synchronized, thread-safe queue was modeled after ringbuffer example from boost?! and/or a Herb Sutter column?!
ScopeValue< RunState > run_state
current RunState
virtual ~Impl()
Stops and interrupts thread if necessary.
void DetachFrame(gui::CChannelFrame *const _cframe)
Detaches a CChannelFrame as observer from the DisplayController.
void Set(const bool &_a=true)
void DetachFrame(gui::CHistogramFrame *const _hframe)
Detaches a CHistogramFrame as observer from the DisplayController.
ScopeNumber< uint32_t > area
the number of this area
Impl(const Impl &i)
disable copy
Parameters for all frames/windows on screen.
std::array< std::vector< gui::CHistogramFrame *const >, SCOPE_NAREAS > histogramframes
Vector of CHistogramFrame observers.
void UpdateStatusInFrames(const RunState &_rs)
Calls CChannelFrame::UpdateStatus and CHistogramFrame::UpdateStatus in all attached frames...
Base class for all controllers.
T Dequeue()
Dequeues front element, waits indefinitely if queue is empty.
virtual void UpdateStatus(const RunState &_rs)
Updates the statusstr and send RunUpdateStatusbar to the Active object.
SynchronizedQueue< ScopeMessage< SCOPE_MULTIIMAGEPTR_T > > *const input_queue
Input queue with multi images from the PipelineController.
void SetHistogramLimits(const uint32_t &_area, const uint32_t &_channel, const uint16_t &_lower, const uint16_t &_upper)
Go through all CChannelFrames of that area and set the histogram limits there.