Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 33 additions & 6 deletions source/MRViewer/MRProgressBar.cpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
#include "MRProgressBar.h"
#include "MRViewer.h"
#include <MRMesh/MRSystem.h>
#include "MRMesh/MRSystem.h"
#include "ImGuiMenu.h"
#include "ImGuiHelpers.h"
#include "MRPch/MRSpdlog.h"
#include "MRPch/MRWasm.h"
#include <GLFW/glfw3.h>

Expand Down Expand Up @@ -93,7 +95,7 @@ void ProgressBar::order( const char* name, const std::function<void()>& task, in
taskCount );
}

void ProgressBar::orderWithMainThreadPostProcessing( const char* name, const std::function< std::function<void()>() >& task, int taskCount )
void ProgressBar::orderWithMainThreadPostProcessing( const char* name, TaskWithMainThreadPostProcessing task, int taskCount )
{
auto& instance = instance_();
if ( isFinished() && instance.thread_.joinable() )
Expand Down Expand Up @@ -132,14 +134,12 @@ void ProgressBar::orderWithMainThreadPostProcessing( const char* name, const std
instance.thread_ = std::thread( [task, &instance] ()
{
SetCurrentThreadName( "ProgressBar" );
instance.onFinish_ = task();
instance.finish_();
instance.tryRunTask_( task );
} );
#else
staticTaskForLaterCall = [&instance, task] ()
{
instance.onFinish_ = task();
instance.finish_();
instance.tryRunTask_( task );
};
emscripten_async_call( asyncCallTask, nullptr, 200 );
#endif
Expand Down Expand Up @@ -248,6 +248,33 @@ ProgressBar::~ProgressBar()
thread_.join();
}

void ProgressBar::tryRunTask_( TaskWithMainThreadPostProcessing task )
{
try
{
onFinish_ = task();
}
catch ( const std::bad_alloc& badAllocE )
{
onFinish_ = [msg = std::string( badAllocE.what() )]()
{
spdlog::error( msg );
if ( auto menu = getViewerInstance().getMenuPlugin() )
menu->showErrorModal( "Device ran out of memory during this operation." );
};
}
catch ( const std::exception& e )
{
onFinish_ = [msg = std::string( e.what() )]()
{
spdlog::error( msg );
if ( auto menu = getViewerInstance().getMenuPlugin() )
menu->showErrorModal( msg );
};
}
finish_();
}

void ProgressBar::postEvent_()
{
// do not do it too frequently not to overload the renderer
Expand Down
7 changes: 6 additions & 1 deletion source/MRViewer/MRProgressBar.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,15 @@ namespace MR
class ProgressBar
{
public:
using TaskWithMainThreadPostProcessing = std::function< std::function<void()>() >;
// this function should be called only once for each frame (it is called in MR::Menu (MR::RibbonMenu))
MRVIEWER_API static void setup( float scaling );

// this shall be called in order to start concurrent task execution with progress bar display
MRVIEWER_API static void order(const char * name, const std::function<void()>& task, int taskCount = 1 );

// in this version the task returns a function to be executed in main thread
MRVIEWER_API static void orderWithMainThreadPostProcessing(const char * name, const std::function< std::function<void()> () >& task, int taskCount = 1 );
MRVIEWER_API static void orderWithMainThreadPostProcessing( const char* name, TaskWithMainThreadPostProcessing task, int taskCount = 1 );

MRVIEWER_API static bool isCanceled();

Expand Down Expand Up @@ -49,6 +50,10 @@ class ProgressBar
ProgressBar();
~ProgressBar();

// cover task execution with try catch block
// if catches exception shows error in main thread overriding user defined main thread post processing
void tryRunTask_( TaskWithMainThreadPostProcessing task );

void postEvent_();
void finish_();

Expand Down