Initial commit

This commit is contained in:
2018-10-14 19:07:06 -05:00
commit 4fb58b4324
22 changed files with 794 additions and 0 deletions

36
src/CMakeLists.txt Normal file
View File

@@ -0,0 +1,36 @@
project(bullock)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
find_package(Qt5Widgets)
set(CMAKE_AUTOMOC ON)
add_executable(
bullock MACOSX_BUNDLE
main.cpp
mainwindow.cpp
processdata.cpp
procselector.cpp
server.cpp
traceeventmodel.cpp
traceview.cpp
)
target_link_libraries(
bullock
Qt5::Core
Qt5::Network
Qt5::Widgets
)
if(APPLE)
set_target_properties(bullock PROPERTIES MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/Info.plist)
endif()
install(
TARGETS
bullock
RUNTIME DESTINATION
${BULLOCK_DIST_BIN}
BUNDLE DESTINATION .
)

29
src/Info.plist Normal file
View File

@@ -0,0 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleExecutable</key>
<string>nostalgia-studio</string>
<key>CFBundleGetInfoString</key>
<string>Nostalgia Studio</string>
<key>CFBundleIconFile</key>
<string></string>
<key>CFBundleIdentifier</key>
<string>net.drinkingtea.nostalgia.studio</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleVersion</key>
<string>1.2.8</string>
<key>LSMinimumSystemVersion</key>
<string>10.13.0</string>
<!-- HiDPI -->
<key>NSPrincipalClass</key>
<string>NSApplication</string>
<key>NSHighResolutionCapable</key>
<string>True</string>
<key>NSHumanReadableCopyright</key>
<string>Copyright (c) 2016-2018 Gary Talent &lt;gtalent2@gmail.com&gt;</string>
</dict>
</plist>

26
src/main.cpp Normal file
View File

@@ -0,0 +1,26 @@
/*
* Copyright 2018 gtalent2@gmail.com
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
#include <QApplication>
#include "server.hpp"
#include "mainwindow.hpp"
int main(int argc, char **args) {
QApplication app(argc, args);
LogServer server;
MainWindow w;
app.setApplicationName(w.windowTitle());
w.show();
QObject::connect(&server, &LogServer::newDataFeed, &w, &MainWindow::addDataFeed);
return app.exec();
}

66
src/mainwindow.cpp Normal file
View File

@@ -0,0 +1,66 @@
/*
* Copyright 2018 gtalent2@gmail.com
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
#include <QAction>
#include <QApplication>
#include <QDateTime>
#include <QDesktopWidget>
#include <QHBoxLayout>
#include <QMenuBar>
#include <QSplitter>
#include "traceview.hpp"
#include "mainwindow.hpp"
MainWindow::MainWindow() {
setWindowTitle(tr("Bullock"));
auto screenSize = QApplication::desktop()->screenGeometry();
constexpr auto sizePct = 0.85;
resize(screenSize.width() * sizePct, screenSize.height() * sizePct);
move(-x(), -y());
move(screenSize.width() * (1 - sizePct) / 2, screenSize.height() * (1 - sizePct) / 2);
auto central = new QWidget(this);
auto splitter = new QSplitter(central);
auto leftPane = new QWidget(this);
auto leftPaneSplitter = new QSplitter(Qt::Vertical, leftPane);
m_procSelector = new ProcessSelector(leftPaneSplitter);
leftPaneSplitter->addWidget(m_procSelector);
splitter->addWidget(leftPaneSplitter);
splitter->addWidget(new TraceView(splitter));
splitter->setStretchFactor(1, 3);
setCentralWidget(splitter);
setupMenu();
}
MainWindow::~MainWindow() {
}
void MainWindow::addDataFeed(DataFeed *feed) {
m_procData.push_back(feed->procData());
auto time = QDateTime::currentDateTime();
m_procSelector->addProcess(time.toString());
}
void MainWindow::setupMenu() {
auto menu = menuBar();
auto fileMenu = menu->addMenu(tr("&File"));
auto helpMenu = menu->addMenu(tr("&Help"));
auto quit = fileMenu->addAction(tr("&Quit"));
quit->setShortcuts(QKeySequence::Quit);
quit->setStatusTip(tr("Quit application"));
connect(quit, &QAction::triggered, this, &MainWindow::close);
helpMenu->addAction(tr("&About"));
}

32
src/mainwindow.hpp Normal file
View File

@@ -0,0 +1,32 @@
/*
* Copyright 2018 gtalent2@gmail.com
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
#include <QMainWindow>
#include "procselector.hpp"
#include "server.hpp"
class MainWindow: public QMainWindow {
Q_OBJECT
private:
QVector<QSharedPointer<ProcessData>> m_procData;
ProcessSelector *m_procSelector = nullptr;
public:
MainWindow();
~MainWindow();
public slots:
void addDataFeed(DataFeed*);
private:
void setupMenu();
};

40
src/processdata.cpp Normal file
View File

@@ -0,0 +1,40 @@
/*
* Copyright 2018 gtalent2@gmail.com
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
#include <QJsonArray>
#include "processdata.hpp"
Field::Field(QJsonObject field) {
this->name = field["name"].toString();
this->type = field["field_type"].toString();
this->value = field["value"].toString();
auto fields = field["fields"].toArray();
for (auto field : fields) {
this->fields.push_back(field.toObject());
}
}
Frame::Frame(QJsonObject frame) {
this->arch = frame["arch"].toString();
this->file = frame["file"].toString();
this->line = frame["line"].toDouble();
auto fields = frame["fields"].toArray();
for (auto field : fields) {
this->fields.push_back(field.toObject());
}
}
TraceEvent::TraceEvent(QJsonObject tp) {
this->logMsg = tp["trace_msg"].toString();
auto frames = tp["frames"].toArray();
for (auto frame : frames) {
this->frames.push_back(frame.toObject());
}
}

47
src/processdata.hpp Normal file
View File

@@ -0,0 +1,47 @@
/*
* Copyright 2018 gtalent2@gmail.com
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
#pragma once
#include <QJsonObject>
#include <QStringList>
#include <QVector>
struct Field {
QString name;
QString type;
QString value;
QVector<Field> fields;
Field(QJsonObject field = {});
};
struct Frame {
QString arch;
QString file;
int line = 0;
QVector<Field> fields;
Frame(QJsonObject frame = {});
};
struct TraceEvent {
QString channel;
QString logMsg;
QVector<Frame> frames;
TraceEvent(QJsonObject tp = {});
};
struct ProcessData {
QString cmd;
QVector<TraceEvent> traceEvents;
};

20
src/procselector.cpp Normal file
View File

@@ -0,0 +1,20 @@
#include <QLabel>
#include <QVBoxLayout>
#include "procselector.hpp"
ProcessSelector::ProcessSelector(QWidget *parent): QWidget(parent) {
auto lyt = new QVBoxLayout(this);
lyt->addWidget(new QLabel(tr("Processes"), this));
lyt->addWidget(m_list);
m_list->addItem(tr("Most Recent"));
m_list->setCurrentRow(RowLatest);
}
void ProcessSelector::addProcess(QString procKey) {
m_list->insertItem(1, procKey);
if (m_list->currentRow() == RowLatest) {
emit selectionChanged(procKey);
}
}

33
src/procselector.hpp Normal file
View File

@@ -0,0 +1,33 @@
/*
* Copyright 2018 gtalent2@gmail.com
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
#pragma once
#include <QListWidget>
#include <QWidget>
class ProcessSelector: public QWidget {
Q_OBJECT
private:
enum Rows {
RowLatest = 0
};
QListWidget *m_list = new QListWidget(this);
public:
ProcessSelector(QWidget *parent = nullptr);
public slots:
void addProcess(QString procKey);
signals:
void selectionChanged(QString procKey);
};

53
src/server.cpp Normal file
View File

@@ -0,0 +1,53 @@
/*
* Copyright 2018 gtalent2@gmail.com
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
#include <QDebug>
#include "server.hpp"
DataFeed::DataFeed(QIODevice *dev): QObject(dev) {
m_dev = dev;
connect(m_dev, &QIODevice::readyRead, this, &DataFeed::handleInit);
}
QSharedPointer<ProcessData> DataFeed::procData() {
return m_procData;
}
void DataFeed::handleInit() {
auto doc = QJsonDocument::fromJson(m_dev->readLine());
if (doc.isObject()) {
auto msg = doc.object();
if (msg["type"].toString() == "Init") {
disconnect(m_dev, &QIODevice::readyRead, this, &DataFeed::handleInit);
connect(m_dev, &QIODevice::readyRead, this, &DataFeed::read);
}
}
}
void DataFeed::read() {
while (m_dev->bytesAvailable()) {
auto doc = QJsonDocument::fromJson(m_dev->readLine());
if (m_procData) {
m_procData->traceEvents.push_back(doc.object());
}
}
}
LogServer::LogServer() {
m_server->listen(QHostAddress::LocalHost, 5590);
connect(m_server, &QTcpServer::newConnection, this, &LogServer::handleConnection);
}
void LogServer::handleConnection() {
auto conn = m_server->nextPendingConnection();
connect(conn, &QAbstractSocket::disconnected, conn, &QObject::deleteLater);
connect(this, &QObject::destroyed, conn, &QObject::deleteLater);
emit newDataFeed(new DataFeed(conn));
}

53
src/server.hpp Normal file
View File

@@ -0,0 +1,53 @@
/*
* Copyright 2018 gtalent2@gmail.com
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
#pragma once
#include <memory>
#include <QJsonDocument>
#include <QPointer>
#include <QSharedPointer>
#include <QTcpServer>
#include <QTcpSocket>
#include "processdata.hpp"
class DataFeed: public QObject {
Q_OBJECT
private:
QSharedPointer<ProcessData> m_procData = QSharedPointer<ProcessData>(new ProcessData);
QIODevice *m_dev = nullptr;
public:
DataFeed(QIODevice *dev);
QSharedPointer<ProcessData> procData();
public slots:
void handleInit();
void read();
};
class LogServer: public QObject {
Q_OBJECT
private:
QPointer<QTcpServer> m_server = new QTcpServer(this);
public:
LogServer();
public slots:
void handleConnection();
signals:
void newDataFeed(DataFeed*);
};

25
src/traceeventmodel.cpp Normal file
View File

@@ -0,0 +1,25 @@
/*
* Copyright 2018 gtalent2@gmail.com
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
#include "traceeventmodel.hpp"
int TraceEventModel::rowCount(const QModelIndex &parent) const {
if (m_procData) {
return m_procData->traceEvents.size();
} else {
return 0;
}
}
int TraceEventModel::columnCount(const QModelIndex &parent) const {
return Column::End;
}
QVariant TraceEventModel::data(const QModelIndex &index, int role) const {
return {};
}

34
src/traceeventmodel.hpp Normal file
View File

@@ -0,0 +1,34 @@
/*
* Copyright 2018 gtalent2@gmail.com
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
#pragma once
#include "processdata.hpp"
#include <QAbstractItemModel>
class TraceEventModel: public QAbstractItemModel {
Q_OBJECT
private:
enum Column {
Channel,
Message,
End
};
ProcessData *m_procData = nullptr;
public:
int rowCount(const QModelIndex &parent = QModelIndex()) const override ;
int columnCount(const QModelIndex &parent = QModelIndex()) const override;
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
};

18
src/traceview.cpp Normal file
View File

@@ -0,0 +1,18 @@
/*
* Copyright 2018 gtalent2@gmail.com
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
#include <QHBoxLayout>
#include <QTableView>
#include "traceview.hpp"
TraceView::TraceView(QWidget *parent): QWidget(parent) {
auto lyt = new QHBoxLayout;
setLayout(lyt);
lyt->addWidget(new QTableView(this));
}

19
src/traceview.hpp Normal file
View File

@@ -0,0 +1,19 @@
/*
* Copyright 2018 gtalent2@gmail.com
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
#pragma once
#include <QWidget>
class TraceView: public QWidget {
Q_OBJECT
public:
TraceView(QWidget *parent = nullptr);
};