mirror of
https://git.mirrors.martin98.com/https://github.com/Ultimaker/Cura
synced 2025-04-16 18:59:39 +08:00
Cleaned up and bug fixed the command loop.
CURA-3335 Single instance Cura and model reloading
This commit is contained in:
parent
0e306df1bc
commit
412e299f0c
@ -1,9 +1,7 @@
|
||||
# Copyright (c) 2015 Ultimaker B.V.
|
||||
# Cura is released under the terms of the AGPLv3 or higher.
|
||||
import json
|
||||
|
||||
from PyQt5.QtCore import QTextStream
|
||||
from PyQt5.QtNetwork import QLocalServer
|
||||
from PyQt5.QtNetwork import QLocalSocket
|
||||
|
||||
from UM.Qt.QtApplication import QtApplication
|
||||
from UM.Scene.SceneNode import SceneNode
|
||||
@ -63,7 +61,8 @@ import numpy
|
||||
import copy
|
||||
import urllib.parse
|
||||
import os
|
||||
|
||||
import argparse
|
||||
import json
|
||||
|
||||
numpy.seterr(all="ignore")
|
||||
|
||||
@ -430,6 +429,7 @@ class CuraApplication(QtApplication):
|
||||
parser.add_argument("file", nargs="*", help="Files to load after starting the application.")
|
||||
parser.add_argument("--single-instance", action="store_true", default=False)
|
||||
|
||||
# Set up a local socket server which listener which coordinates single instances Curas and accepts commands.
|
||||
def _setUpSingleInstanceServer(self):
|
||||
if self.getCommandLineOption("single_instance", False):
|
||||
self.__single_instance_server = QLocalServer()
|
||||
@ -437,25 +437,79 @@ class CuraApplication(QtApplication):
|
||||
self.__single_instance_server.listen("ultimaker-cura")
|
||||
|
||||
def _singleInstanceServerNewConnection(self):
|
||||
Logger.log('d', 'Saw something on the single instance server')
|
||||
other_cura_connection = self.__single_instance_server.nextPendingConnection()
|
||||
if other_cura_connection is not None:
|
||||
def readyRead():
|
||||
while other_cura_connection.canReadLine():
|
||||
line = other_cura_connection.readLine()
|
||||
payload = json.loads(str(line, encoding="ASCII").strip())
|
||||
command = payload["command"]
|
||||
if command == "clear-all":
|
||||
self.deleteAll()
|
||||
Logger.log("i", "New connection recevied on our single-instance server")
|
||||
remote_cura_connection = self.__single_instance_server.nextPendingConnection()
|
||||
|
||||
elif command == "open":
|
||||
self.deleteAll()
|
||||
self._openFile(payload["filePath"])
|
||||
if remote_cura_connection is not None:
|
||||
def readCommands():
|
||||
line = remote_cura_connection.readLine()
|
||||
while len(line) != 0: # There is also a .canReadLine()
|
||||
try:
|
||||
Logger.log('d', "JSON command: " + str(line, encoding="ASCII"))
|
||||
payload = json.loads(str(line, encoding="ASCII").strip())
|
||||
command = payload["command"]
|
||||
|
||||
elif command == "focus":
|
||||
self.focusWindow()
|
||||
# Command: Remove all models from the build plate.
|
||||
if command == "clear-all":
|
||||
self.deleteAll()
|
||||
|
||||
other_cura_connection.readyRead.connect(readyRead)
|
||||
# Command: Load a model file
|
||||
elif command == "open":
|
||||
self._openFile(payload["filePath"])
|
||||
# FIXME ^ this method is async and we really should wait until
|
||||
# the file load is complete before processing more commands.
|
||||
|
||||
# Command: Activate the window and bring it to the top.
|
||||
elif command == "focus":
|
||||
self.getMainWindow().raise_()
|
||||
self.focusWindow()
|
||||
|
||||
else:
|
||||
Logger.log("w", "Received an unrecognized command " + str(command))
|
||||
except json.decoder.JSONDecodeError as ex:
|
||||
Logger.log("w", "Unable to parse JSON command in _singleInstanceServerNewConnection(): " + repr(ex))
|
||||
line = remote_cura_connection.readLine()
|
||||
|
||||
remote_cura_connection.readyRead.connect(readCommands)
|
||||
remote_cura_connection.disconnected.connect(readCommands) # Get any last commands before it is destroyed.
|
||||
|
||||
## Perform any checks before creating the main application.
|
||||
#
|
||||
# This should be called directly before creating an instance of CuraApplication.
|
||||
# \returns \type{bool} True if the whole Cura app should continue running.
|
||||
@classmethod
|
||||
def preStartUp(cls):
|
||||
# Peek the arguments and look for the 'single-instance' flag.
|
||||
parser = argparse.ArgumentParser(prog="cura") # pylint: disable=bad-whitespace
|
||||
CuraApplication.addCommandLineOptions(parser)
|
||||
parsed_command_line = vars(parser.parse_args())
|
||||
|
||||
if "single_instance" in parsed_command_line and parsed_command_line["single_instance"]:
|
||||
Logger.log("i", "Checking for the presence of an ready running Cura instance.")
|
||||
single_instance_socket = QLocalSocket()
|
||||
single_instance_socket.connectToServer("ultimaker-cura")
|
||||
single_instance_socket.waitForConnected()
|
||||
if single_instance_socket.state() == QLocalSocket.ConnectedState:
|
||||
Logger.log("i", "Connection has been made to the single-instance Cura socket.")
|
||||
|
||||
# Protocol is one line of JSON terminated with a carriage return.
|
||||
# "command" field is required and holds the name of the command to execute.
|
||||
# Other fields depend on the command.
|
||||
|
||||
payload = {"command": "clear-all"}
|
||||
single_instance_socket.write(bytes(json.dumps(payload) + "\n", encoding="ASCII"))
|
||||
|
||||
payload = {"command": "focus"}
|
||||
single_instance_socket.write(bytes(json.dumps(payload) + "\n", encoding="ASCII"))
|
||||
|
||||
if len(parsed_command_line["file"]) != 0:
|
||||
for filename in parsed_command_line["file"]:
|
||||
payload = {"command": "open", "filePath": filename}
|
||||
single_instance_socket.write(bytes(json.dumps(payload) + "\n", encoding="ASCII"))
|
||||
single_instance_socket.flush()
|
||||
single_instance_socket.close()
|
||||
return False
|
||||
return True
|
||||
|
||||
def run(self):
|
||||
self.showSplashMessage(self._i18n_catalog.i18nc("@info:progress", "Setting up scene..."))
|
||||
|
37
cura_app.py
37
cura_app.py
@ -2,14 +2,10 @@
|
||||
|
||||
# Copyright (c) 2015 Ultimaker B.V.
|
||||
# Cura is released under the terms of the AGPLv3 or higher.
|
||||
import argparse
|
||||
import json
|
||||
import os
|
||||
import sys
|
||||
import platform
|
||||
import time
|
||||
|
||||
from PyQt5.QtNetwork import QLocalSocket
|
||||
from UM.Platform import Platform
|
||||
|
||||
#WORKAROUND: GITHUB-88 GITHUB-385 GITHUB-612
|
||||
@ -61,36 +57,9 @@ if Platform.isWindows() and hasattr(sys, "frozen"):
|
||||
# Force an instance of CuraContainerRegistry to be created and reused later.
|
||||
cura.Settings.CuraContainerRegistry.getInstance()
|
||||
|
||||
# Peek the arguments and look for the 'single-instance' flag.
|
||||
parser = argparse.ArgumentParser(prog="cura") # pylint: disable=bad-whitespace
|
||||
cura.CuraApplication.CuraApplication.addCommandLineOptions(parser)
|
||||
parsed_command_line = vars(parser.parse_args())
|
||||
|
||||
if "single_instance" in parsed_command_line and parsed_command_line["single_instance"]:
|
||||
print("Check for single instance")
|
||||
single_instance_socket = QLocalSocket()
|
||||
single_instance_socket.connectToServer("ultimaker-cura")
|
||||
single_instance_socket.waitForConnected()
|
||||
if single_instance_socket.state() == QLocalSocket.ConnectedState:
|
||||
print("Connected to the other Cura instance.")
|
||||
print(repr(parsed_command_line))
|
||||
|
||||
payload = {"command": "clear-all"}
|
||||
single_instance_socket.write(bytes(json.dumps(payload) + "\n", encoding="ASCII"))
|
||||
|
||||
payload = {"command": "focus"}
|
||||
single_instance_socket.write(bytes(json.dumps(payload) + "\n", encoding="ASCII"))
|
||||
|
||||
if len(parsed_command_line["file"]) != 0:
|
||||
for filename in parsed_command_line["file"]:
|
||||
payload = { "command": "open", "filePath": filename }
|
||||
single_instance_socket.write(bytes(json.dumps(payload) + "\n", encoding="ASCII"))
|
||||
|
||||
single_instance_socket.flush()
|
||||
|
||||
|
||||
single_instance_socket.close()
|
||||
sys.exit(0)
|
||||
# This prestart up check is needed to determine if we should start the application at all.
|
||||
if not cura.CuraApplication.CuraApplication.preStartUp():
|
||||
sys.exit(0)
|
||||
|
||||
app = cura.CuraApplication.CuraApplication.getInstance()
|
||||
app.run()
|
||||
|
Loading…
x
Reference in New Issue
Block a user