CoCalc provides the best real-time collaborative environment for Jupyter Notebooks, LaTeX documents, and SageMath, scalable from individual users to large groups and classes!
CoCalc provides the best real-time collaborative environment for Jupyter Notebooks, LaTeX documents, and SageMath, scalable from individual users to large groups and classes!
Path: blob/master/Core/Debugger/WebSocket/LogBroadcaster.cpp
Views: 1401
// Copyright (c) 2018- PPSSPP Project.12// This program is free software: you can redistribute it and/or modify3// it under the terms of the GNU General Public License as published by4// the Free Software Foundation, version 2.0 or later versions.56// This program is distributed in the hope that it will be useful,7// but WITHOUT ANY WARRANTY; without even the implied warranty of8// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the9// GNU General Public License 2.0 for more details.1011// A copy of the GPL 2.0 should have been included with the program.12// If not, see http://www.gnu.org/licenses/1314// Official git repository and contact information can be found at15// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.1617#include <algorithm>18#include <mutex>19#include "Common/Log/LogManager.h"20#include "Core/Debugger/WebSocket/LogBroadcaster.h"21#include "Core/Debugger/WebSocket/WebSocketUtils.h"2223class DebuggerLogListener : public LogListener {24public:25void Log(const LogMessage &msg) override {26std::lock_guard<std::mutex> guard(lock_);27messages_[nextMessage_] = msg;28nextMessage_++;29if (nextMessage_ >= BUFFER_SIZE)30nextMessage_ -= BUFFER_SIZE;31count_++;32}3334std::vector<LogMessage> GetMessages() {35std::lock_guard<std::mutex> guard(lock_);36int splitPoint;37int readCount;38if (read_ + BUFFER_SIZE < count_) {39// We'll start with our oldest then.40splitPoint = nextMessage_;41readCount = Count();42} else {43splitPoint = read_;44readCount = count_ - read_;45}4647read_ = count_;4849std::vector<LogMessage> results;50int splitEnd = std::min(splitPoint + readCount, (int)BUFFER_SIZE);51for (int i = splitPoint; i < splitEnd; ++i) {52results.push_back(messages_[i]);53readCount--;54}55for (int i = 0; i < readCount; ++i) {56results.push_back(messages_[i]);57}5859return results;60}6162int Count() const {63return count_ < BUFFER_SIZE ? count_ : BUFFER_SIZE;64}6566private:67enum { BUFFER_SIZE = 1024 };68LogMessage messages_[BUFFER_SIZE];69std::mutex lock_;70int nextMessage_ = 0;71int count_ = 0;72int read_ = 0;73};7475LogBroadcaster::LogBroadcaster() {76listener_ = new DebuggerLogListener();77if (LogManager::GetInstance())78LogManager::GetInstance()->AddListener(listener_);79}8081LogBroadcaster::~LogBroadcaster() {82if (LogManager::GetInstance())83LogManager::GetInstance()->RemoveListener(listener_);84delete listener_;85}8687struct DebuggerLogEvent {88const LogMessage &l;8990operator std::string() {91JsonWriter j;92j.begin();93j.writeString("event", "log");94j.writeString("timestamp", l.timestamp);95j.writeString("header", l.header);96j.writeString("message", l.msg);97j.writeInt("level", (int)l.level);98j.writeString("channel", l.log);99j.end();100return j.str();101}102};103104// Log message (log)105//106// Sent unexpectedly with these properties:107// - timestamp: string timestamp of event.108// - header: string header information about the event (including file/line.)109// - message: actual log message as a string.110// - level: number severity level (1 = highest.)111// - channel: string describing log channel / grouping.112void LogBroadcaster::Broadcast(net::WebSocketServer *ws) {113auto messages = listener_->GetMessages();114for (auto msg : messages) {115ws->Send(DebuggerLogEvent{msg});116}117}118119120