1 #ifndef slic3r_InstanceCheck_hpp_ 2 #define slic3r_InstanceCheck_hpp_ 3 4 #include "Event.hpp" 5 6 #if _WIN32 7 #include <windows.h> 8 #endif //_WIN32 9 10 #include <string> 11 12 #include <boost/filesystem.hpp> 13 14 #if __linux__ 15 #include <boost/thread.hpp> 16 #include <mutex> 17 #include <condition_variable> 18 #endif // __linux__ 19 20 21 namespace Slic3r { 22 // checks for other running instances and sends them argv, 23 // if there is --single-instance argument or AppConfig is set to single_instance=1 24 // returns true if this instance should terminate 25 bool instance_check(int argc, char** argv, bool app_config_single_instance); 26 27 #if __APPLE__ 28 // apple implementation of inner functions of instance_check 29 // in InstanceCheckMac.mm 30 void send_message_mac(const std::string& msg, const std::string& version); 31 32 bool unlock_lockfile(const std::string& name, const std::string& path); 33 #endif //__APPLE__ 34 35 namespace GUI { 36 37 class MainFrame; 38 39 #if __linux__ 40 #define BACKGROUND_MESSAGE_LISTENER 41 #endif // __linux__ 42 43 using LoadFromOtherInstanceEvent = Event<std::vector<boost::filesystem::path>>; 44 wxDECLARE_EVENT(EVT_LOAD_MODEL_OTHER_INSTANCE, LoadFromOtherInstanceEvent); 45 46 using InstanceGoToFrontEvent = SimpleEvent; 47 wxDECLARE_EVENT(EVT_INSTANCE_GO_TO_FRONT, InstanceGoToFrontEvent); 48 49 class OtherInstanceMessageHandler 50 { 51 public: 52 OtherInstanceMessageHandler() = default; 53 OtherInstanceMessageHandler(OtherInstanceMessageHandler const&) = delete; 54 void operator=(OtherInstanceMessageHandler const&) = delete; ~OtherInstanceMessageHandler()55 ~OtherInstanceMessageHandler() { assert(!m_initialized); } 56 57 // inits listening, on each platform different. On linux starts background thread 58 void init(wxEvtHandler* callback_evt_handler); 59 // stops listening, on linux stops the background thread 60 void shutdown(MainFrame* main_frame); 61 62 //finds paths to models in message(= command line arguments, first should be prusaSlicer executable) 63 //and sends them to plater via LoadFromOtherInstanceEvent 64 //security of messages: from message all existing paths are proccesed to load model 65 // win32 - anybody who has hwnd can send message. 66 // mac - anybody who posts notification with name:@"OtherPrusaSlicerTerminating" 67 // linux - instrospectable on dbus 68 void handle_message(const std::string& message); 69 #ifdef _WIN32 70 static void init_windows_properties(MainFrame* main_frame, size_t instance_hash); 71 #endif //WIN32 72 private: 73 bool m_initialized { false }; 74 wxEvtHandler* m_callback_evt_handler { nullptr }; 75 76 #ifdef BACKGROUND_MESSAGE_LISTENER 77 //worker thread to listen incoming dbus communication 78 boost::thread m_thread; 79 std::condition_variable m_thread_stop_condition; 80 mutable std::mutex m_thread_stop_mutex; 81 bool m_stop{ false }; 82 bool m_start{ true }; 83 84 // background thread method 85 void listen(); 86 #endif //BACKGROUND_MESSAGE_LISTENER 87 88 #if __APPLE__ 89 //implemented at InstanceCheckMac.mm 90 void register_for_messages(const std::string &version_hash); 91 void unregister_for_messages(); 92 // Opaque pointer to RemovableDriveManagerMM 93 void* m_impl_osx; 94 public: 95 void bring_instance_forward(); 96 #endif //__APPLE__ 97 98 }; 99 } // namespace GUI 100 } // namespace Slic3r 101 #endif // slic3r_InstanceCheck_hpp_ 102