single slicer instance

check for other instances during startup
send message with command line arguments if found and terminate
listen for those messages and load objects from paths in messages from them
This commit is contained in:
David Kocik 2020-04-29 10:50:28 +02:00
parent 9cb5975956
commit d828a1e80b
16 changed files with 841 additions and 29 deletions

View file

@ -0,0 +1,91 @@
#ifndef slic3r_InstanceCheck_hpp_
#define slic3r_InstanceCheck_hpp_
#include "Event.hpp"
#if _WIN32
#include <windows.h>
#endif //_WIN32
#include <string>
#include <boost/filesystem.hpp>
#include <boost/thread.hpp>
#include <tbb/mutex.h>
#include <condition_variable>
namespace Slic3r {
// checks for other running instances and sends them argv,
// if there is --single-instance argument or AppConfig is set to single_instance=1
// returns true if this instance should terminate
bool instance_check(int argc, char** argv, bool app_config_single_instance);
#if __APPLE__
// apple implementation of inner functions of instance_check
// in InstanceCheckMac.mm
void send_message_mac(const std::string msg);
#endif //__APPLE__
namespace GUI {
#if __linux__
#define BACKGROUND_MESSAGE_LISTENER
#endif // __linux__
using LoadFromOtherInstanceEvent = Event<std::vector<boost::filesystem::path>>;
wxDECLARE_EVENT(EVT_LOAD_MODEL_OTHER_INSTANCE, LoadFromOtherInstanceEvent);
using InstanceGoToFrontEvent = SimpleEvent;
wxDECLARE_EVENT(EVT_INSTANCE_GO_TO_FRONT, InstanceGoToFrontEvent);
class OtherInstanceMessageHandler
{
public:
OtherInstanceMessageHandler() = default;
OtherInstanceMessageHandler(OtherInstanceMessageHandler const&) = delete;
void operator=(OtherInstanceMessageHandler const&) = delete;
~OtherInstanceMessageHandler() { assert(!m_initialized); }
// inits listening, on each platform different. On linux starts background thread
void init(wxEvtHandler* callback_evt_handler);
// stops listening, on linux stops the background thread
void shutdown();
//finds paths to models in message(= command line arguments, first should be prusaSlicer executable)
//and sends them to plater via LoadFromOtherInstanceEvent
//security of messages: from message all existing paths are proccesed to load model
// win32 - anybody who has hwnd can send message.
// mac - anybody who posts notification with name:@"OtherPrusaSlicerTerminating"
// linux - instrospectable on dbus
void handle_message(const std::string message);
private:
bool m_initialized { false };
wxEvtHandler* m_callback_evt_handler { nullptr };
#ifdef BACKGROUND_MESSAGE_LISTENER
//worker thread to listen incoming dbus communication
boost::thread m_thread;
std::condition_variable m_thread_stop_condition;
mutable std::mutex m_thread_stop_mutex;
bool m_stop{ false };
bool m_start{ true };
// background thread method
void listen();
#endif //BACKGROUND_MESSAGE_LISTENER
#if __APPLE__
//implemented at InstanceCheckMac.mm
void register_for_messages();
void unregister_for_messages();
// Opaque pointer to RemovableDriveManagerMM
void* m_impl_osx;
#endif //__APPLE__
};
} // namespace GUI
} // namespace Slic3r
#endif // slic3r_InstanceCheck_hpp_