Skip to content

Commit cbd2be0

Browse files
authored
Merge pull request #1867 from alicevision/dev/nodeComputationDisplay
[ui] node time computation and chunks count in node editor header
2 parents c39f3b8 + 51656db commit cbd2be0

File tree

2 files changed

+53
-18
lines changed

2 files changed

+53
-18
lines changed

meshroom/core/node.py

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -404,6 +404,7 @@ def process(self, forceCompute=False):
404404
global runningProcesses
405405
runningProcesses[self.name] = self
406406
self._status.initStartCompute()
407+
exceptionStatus = None
407408
startTime = time.time()
408409
self.upgradeStatusTo(Status.RUNNING)
409410
self.statThread = stats.StatisticsThread(self)
@@ -412,14 +413,16 @@ def process(self, forceCompute=False):
412413
self.node.nodeDesc.processChunk(self)
413414
except Exception as e:
414415
if self._status.status != Status.STOPPED:
415-
self.upgradeStatusTo(Status.ERROR)
416+
exceptionStatus = Status.ERROR
416417
raise
417418
except (KeyboardInterrupt, SystemError, GeneratorExit) as e:
418-
self.upgradeStatusTo(Status.STOPPED)
419+
exceptionStatus = Status.STOPPED
419420
raise
420421
finally:
421422
self._status.initEndCompute()
422423
self._status.elapsedTime = time.time() - startTime
424+
if exceptionStatus is not None:
425+
self.upgradeStatusTo(exceptionStatus)
423426
logging.info(' - elapsed time: {}'.format(self._status.elapsedTimeStr))
424427
# ask and wait for the stats thread to stop
425428
self.statThread.stopRequest()
@@ -805,6 +808,13 @@ def clearData(self):
805808
shutil.rmtree(self.internalFolder)
806809
self.updateStatusFromCache()
807810

811+
@Slot(result=str)
812+
def getStartDateTime(self):
813+
""" Return the date (str) of the first running chunk """
814+
dateTime = [chunk._status.startDateTime for chunk in self._chunks if chunk._status.status
815+
not in (Status.NONE, Status.SUBMITTED) and chunk._status.startDateTime != ""]
816+
return min(dateTime) if len(dateTime) != 0 else ""
817+
808818
def isAlreadySubmitted(self):
809819
for chunk in self._chunks:
810820
if chunk.isAlreadySubmitted():
@@ -827,6 +837,11 @@ def isSubmittedOrRunning(self):
827837
return True
828838
return False
829839

840+
@Slot(result=bool)
841+
def isRunning(self):
842+
""" Return True if at least one chunk of this Node is running, False otherwise. """
843+
return any(chunk.isRunning() for chunk in self._chunks)
844+
830845
@Slot(result=bool)
831846
def isFinishedOrRunning(self):
832847
""" Return True if all chunks of this Node is either finished or running, False otherwise. """

meshroom/ui/qml/GraphEditor/NodeEditor.qml

Lines changed: 36 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -15,39 +15,56 @@ Panel {
1515
id: root
1616

1717
property variant node
18+
property string globalStatus : node !== null ? node.globalStatus : ""
1819
property bool readOnly: false
1920
property bool isCompatibilityNode: node && node.compatibilityIssue !== undefined
21+
property string nodeStartDateTime: ""
2022

2123
signal attributeDoubleClicked(var mouse, var attribute)
2224
signal upgradeRequest()
2325

2426
title: "Node" + (node !== null ? " - <b>" + node.label + "</b>" + (node.label !== node.defaultLabel ? " (" + node.defaultLabel + ")" : "") : "")
2527
icon: MaterialLabel { text: MaterialIcons.tune }
2628

29+
onGlobalStatusChanged: {
30+
nodeStartDateTime = ""
31+
if (node !== null && node.isRunning()) {
32+
timer.start()
33+
}
34+
else {
35+
timer.stop()
36+
if (node !== null && (node.isFinishedOrRunning() || globalStatus == "ERROR")) {
37+
computationInfo.text = Format.getTimeStr(node.elapsedTime)
38+
}
39+
else{
40+
computationInfo.text = ""
41+
}
42+
}
43+
}
44+
2745
headerBar: RowLayout {
2846
Label {
29-
text: {
30-
if (node !== null && node.isSubmittedOrRunning()) {
31-
// Some chunks might be submitted but they'll all run eventually
32-
if (node.elapsedTime > 0) { // At least a chunk is done running
33-
return "Running for: " + Format.getTimeStr(node.elapsedTime)
34-
} else {
35-
return (node.chunks.count > 1) ? "First chunk running" : "Node running"
47+
id: computationInfo
48+
color: node ? Colors.statusColors[node.globalStatus] : palette.text
49+
Timer {
50+
id: timer
51+
interval: 2500
52+
triggeredOnStart: true
53+
repeat: true
54+
running: node !== null && node.isRunning()
55+
onTriggered: {
56+
if (nodeStartDateTime === "") {
57+
nodeStartDateTime = new Date(node.getStartDateTime()).getTime()
3658
}
37-
} else if (node !== null && node.isFinishedOrRunning()) {
38-
/* Either all chunks finished running or the last one is running
39-
* Placed inside an "else if" instead of "else" to avoid entering the functions
40-
* when there is no real use */
41-
return Format.getTimeStr(node.elapsedTime)
42-
} else {
43-
return ""
59+
var now = new Date().getTime()
60+
parent.text = Format.getTimeStr((now-nodeStartDateTime)/1000)
4461
}
4562
}
4663
padding: 2
4764
font.italic: true
4865
visible: {
4966
if (node !== null) {
50-
if ((node.isFinishedOrRunning() || node.isSubmittedOrRunning())) {
67+
if (node.isFinishedOrRunning() || node.isSubmittedOrRunning() || node.globalStatus=="ERROR") {
5168
return true
5269
}
5370
}
@@ -184,7 +201,10 @@ Panel {
184201
MenuItem {
185202
enabled: root.node !== null
186203
text: "Clear Pending Status"
187-
onClicked: node.clearSubmittedChunks()
204+
onClicked: {
205+
node.clearSubmittedChunks()
206+
timer.stop()
207+
}
188208
}
189209
}
190210
}

0 commit comments

Comments
 (0)