satdump/src-core/handlers/processing_handler.h

119 lines
3.5 KiB
C
Raw Permalink Normal View History

2025-01-02 17:04:32 +01:00
#pragma once
/**
* @file processing_handler.h
*/
#include "handler.h"
#include <thread>
namespace satdump
{
namespace handlers
2025-01-02 17:04:32 +01:00
{
/**
* @brief ProcessingHandler base class
*
* Some handlers implement a lot of processing already in order
* to allow manipulating products, images, or more. Therefore,
* it'd be stupid not to re-use this code for headless
* processing as well! :-)
*
* This is a common interface Handlers can implement if required
* that allows implementing processing in a way common to both
* the UI and headless uses. This implements the multi-threaded
* processing required in the UI as well.
*
* @param is_processing variable to be used in the UI to disable controls
* while processing is ongoing
*/
class ProcessingHandler
{
public:
ProcessingHandler() {}
~ProcessingHandler()
{
if (async_thread.joinable())
async_thread.join();
}
protected:
bool is_processing = false;
2025-09-04 17:44:37 +02:00
std::mutex is_processing_mtx;
2025-01-02 17:04:32 +01:00
/**
* @brief Actual processing function to be implemented by the child class
*/
virtual void do_process() = 0;
std::thread async_thread;
public:
/**
* @brief Performing processing. This is not multi-threaded, intended to call it externally
*/
void process()
{
2025-09-04 17:44:37 +02:00
is_processing_mtx.lock();
2025-01-02 17:04:32 +01:00
is_processing = true;
2025-09-04 17:44:37 +02:00
is_processing_mtx.unlock();
2025-01-02 17:04:32 +01:00
do_process();
2025-09-04 17:44:37 +02:00
is_processing_mtx.lock();
2025-01-02 17:04:32 +01:00
is_processing = false;
2025-09-04 17:44:37 +02:00
is_processing_mtx.unlock();
}
/**
* @brief Set the processing status externally, to force waiting before starting a new thread
* @param v to set if it's processing or not
*/
void set_is_processing(bool v)
{
is_processing_mtx.lock();
is_processing = v;
is_processing_mtx.unlock();
2025-01-02 17:04:32 +01:00
}
2026-02-09 20:02:40 +01:00
/**
* @brief Get the processing status externally
* @return current status
*/
bool get_is_processing()
{
is_processing_mtx.lock();
bool s = is_processing;
is_processing_mtx.unlock();
return s;
}
2025-01-02 17:04:32 +01:00
/**
* @brief Perform processing asynchronously, in a thread
*/
void asyncProcess()
{
2025-09-04 17:44:37 +02:00
is_processing_mtx.lock();
2025-01-02 17:04:32 +01:00
if (is_processing && async_thread.joinable())
{
printf("ALREADY PROCESSING!!!!\n"); // TODOREWORK
2025-09-04 17:44:37 +02:00
is_processing_mtx.unlock();
2025-01-02 17:04:32 +01:00
return;
}
2025-09-04 17:44:37 +02:00
is_processing_mtx.unlock();
2025-01-02 17:04:32 +01:00
try
{
async_thread.join();
}
catch (std::exception &e)
{
}
2025-09-04 17:44:37 +02:00
is_processing_mtx.lock();
2025-01-02 17:04:32 +01:00
is_processing = true;
2025-09-04 17:44:37 +02:00
is_processing_mtx.unlock();
2025-04-14 19:03:42 +01:00
auto fun = [this]() { process(); };
2025-01-02 17:04:32 +01:00
async_thread = std::thread(fun);
}
};
} // namespace handlers
2025-04-14 19:03:42 +01:00
} // namespace satdump