diff --git a/gui/ollie9pclient.cpp b/gui/ollie9pclient.cpp index 6eccf75..7665f3a 100644 --- a/gui/ollie9pclient.cpp +++ b/gui/ollie9pclient.cpp @@ -257,48 +257,70 @@ void Ollie9pClient::stopAgentConnections() } // handleEvent processes a single event from eventwait. -// Event format: "topic [payload]" -// Topics: session.{sid}.{action}, session.{sid}.agent.{aid}.{action} +// Event format: "topic payload" where topic is "session.{sid}.{action}" or +// "session.{sid}.agent.{aid}.{action}" +// Optimized for the hot path: agent.state changes void Ollie9pClient::handleEvent(const QString &eventLine) { if (eventLine.isEmpty()) return; - // Split into topic and payload - int spaceIdx = eventLine.indexOf(' '); - QString topic = spaceIdx > 0 ? eventLine.left(spaceIdx) : eventLine; - QString payload = spaceIdx > 0 ? eventLine.mid(spaceIdx + 1) : QString(); + // Split topic and payload (avoid QString allocation where possible) + const int spaceIdx = eventLine.indexOf(QLatin1Char(' ')); + const QStringView topic = spaceIdx > 0 + ? QStringView(eventLine).left(spaceIdx) + : QStringView(eventLine); + const QStringView payload = spaceIdx > 0 + ? QStringView(eventLine).mid(spaceIdx + 1) + : QStringView(); - QStringList parts = topic.split('.'); - // Expected: session.{sid}.* or session.{sid}.agent.{aid}.* + // Fast path: must start with "session." + if (!topic.startsWith(QLatin1String("session."))) return; - if (parts.size() >= 3 && parts[0] == "session") { - QString sessionId = parts[1]; - QString action = parts[2]; + // Parse: session.{sid}.{rest...} + const int firstDot = 7; // length of "session" + const int secondDot = topic.indexOf(QLatin1Char('.'), firstDot + 1); + if (secondDot < 0) return; + + const QStringView sessionId = topic.mid(firstDot + 1, secondDot - firstDot - 1); + const QStringView rest = topic.mid(secondDot + 1); + + // Check for agent events: "agent.{aid}.{action}" + if (rest.startsWith(QLatin1String("agent."))) { + // Parse agent.{aid}.{action} + const int agentDot = 5; // length of "agent" + const int aidEnd = rest.indexOf(QLatin1Char('.'), agentDot + 1); + if (aidEnd < 0) return; - if (action == "agent" && parts.size() >= 5) { - // Agent event: session.{sid}.agent.{aid}.{action} - QString agentId = parts[3]; - QString agentAction = parts[4]; - QString key = agentKey(sessionId, agentId); + const QStringView agentId = rest.mid(agentDot + 1, aidEnd - agentDot - 1); + const QStringView agentAction = rest.mid(aidEnd + 1); + + if (agentAction == QLatin1String("state")) { + // Hot path: agent state change + if (payload.isEmpty()) return; - if (agentAction == "state") { - // Update cached state - if (!payload.isEmpty() && m_agentStateValues.value(key) != payload) { - m_agentStateValues[key] = payload; - emit agentStateChanged(sessionId, agentId, payload); - // Also update activeState if this is the active agent - if (sessionId == m_activeSessionId && agentId == m_agentId) { - m_activeState = payload; - emit activeStateChanged(); - } + const QString sidStr = sessionId.toString(); + const QString aidStr = agentId.toString(); + const QString key = agentKey(sidStr, aidStr); + const QString payloadStr = payload.toString(); + + if (m_agentStateValues.value(key) != payloadStr) { + m_agentStateValues[key] = payloadStr; + emit agentStateChanged(sidStr, aidStr, payloadStr); + + // Fast check: is this the active agent? + if (sidStr == m_activeSessionId && aidStr == m_agentId) { + m_activeState = payloadStr; + emit activeStateChanged(); } - } else if (agentAction == "new" || agentAction == "kill") { - // Structural change — need full refresh - refreshSessions(); } - } else if (action == "pause" || action == "resume" || - action == "new" || action == "kill" || action == "rename") { - // Session-level structural change — need full refresh + } else if (agentAction == QLatin1String("new") || agentAction == QLatin1String("kill")) { + refreshSessions(); + } + } else { + // Session-level event + if (rest == QLatin1String("pause") || rest == QLatin1String("resume") || + rest == QLatin1String("new") || rest == QLatin1String("kill") || + rest == QLatin1String("rename")) { refreshSessions(); } }