eliminate C++ calls in QML update loop

- computeConnectionColor() in QML instead of ollie.sessionConnectionColor()
  (avoids O(n²) iteration through sessions list)
- Use agent.state from session/idx data directly instead of ollie.agentState()
  (avoids hash lookup per agent per update)

All data now flows from session/idx through m_sessions to QML with no
callbacks into C++ during the update loop.
This commit is contained in:
Levi Neely 2026-08-03 20:13:32 +02:00
parent 8a3d52965e
commit 57b3ce04e3
1 changed files with 19 additions and 10 deletions

View File

@ -126,6 +126,16 @@ ApplicationWindow {
promptInput.forceActiveFocus()
}
// Compute connection color from session data (avoids C++ call)
function computeConnectionColor(sess) {
var paused = sess.paused || false
var connected = sess.connected || false
if (paused && connected) return "yellow" // zombie
if (paused) return "gray" // intentionally paused
if (connected) return "green" // healthy
return "red" // crashed/broken
}
function appendSessionToModel(sess) {
var sessionId = sess.id || ""
var sessionName = sess.name || sessionId
@ -144,19 +154,19 @@ ApplicationWindow {
model: sess.model || "",
displayName: displayLabel,
baseName: sessionName,
connectionColor: ollie.sessionConnectionColor(sessionId)
connectionColor: computeConnectionColor(sess)
})
var agentIds = []
for (var j = 0; j < agents.length; ++j) {
var agent = agents[j]
var liveState = ollie.agentState(sessionId, agent.id)
// Use state from session/idx data directly (already contains agent state)
sessionTreeModel.append({
type: "agent",
parentId: sessionId,
agentId: agent.id,
level: 1,
state: liveState || agent.state || "idle",
state: agent.state || "idle",
connected: agent.connected,
displayName: agent.name
})
@ -242,12 +252,12 @@ ApplicationWindow {
var agentCount = agents.length
var displayLabel = agentCount > 0 ? sessionName + " (" + agentCount + ")" : sessionName
// Update session properties
// Update session properties (use QML-computed color, avoids C++ call)
sessionTreeModel.setProperty(sessionIdx, "displayName", displayLabel)
sessionTreeModel.setProperty(sessionIdx, "baseName", sessionName)
sessionTreeModel.setProperty(sessionIdx, "state", sess.state || "")
sessionTreeModel.setProperty(sessionIdx, "model", sess.model || "")
sessionTreeModel.setProperty(sessionIdx, "connectionColor", ollie.sessionConnectionColor(sessionId))
sessionTreeModel.setProperty(sessionIdx, "connectionColor", computeConnectionColor(sess))
// Build agent lookup
var newAgentIds = {}
@ -262,10 +272,9 @@ ApplicationWindow {
if (item.type === "session") break
if (item.type === "agent" && item.parentId === sessionId) {
if (newAgentIds[item.agentId]) {
// Update agent
// Update agent - use state from session/idx directly
var agent = newAgentIds[item.agentId]
var liveState = ollie.agentState(sessionId, agent.id)
sessionTreeModel.setProperty(idx, "state", liveState || agent.state || "idle")
sessionTreeModel.setProperty(idx, "state", agent.state || "idle")
sessionTreeModel.setProperty(idx, "connected", agent.connected)
sessionTreeModel.setProperty(idx, "displayName", agent.name)
} else {
@ -293,13 +302,13 @@ ApplicationWindow {
if (oldAgentIds[n] === ag.id) { found = true; break }
}
if (!found) {
var liveState2 = ollie.agentState(sessionId, ag.id)
// Use state from session/idx directly
sessionTreeModel.insert(insertIdx, {
type: "agent",
parentId: sessionId,
agentId: ag.id,
level: 1,
state: liveState2 || ag.state || "idle",
state: ag.state || "idle",
connected: ag.connected,
displayName: ag.name
})