Implement event model in C++

Filtering events in JS is too slow with >20,000 events. This moves the
event data model into C++.
This commit is contained in:
Timotej Lazar 2021-09-01 17:13:51 +02:00
parent e9b70c585c
commit cb76fedcbc
No known key found for this signature in database
GPG key ID: B6F38793D143456F
14 changed files with 375 additions and 342 deletions

View file

@ -3,139 +3,35 @@
import QtQuick 2.12
import QtQuick.Controls 2.13
import QtQuick.Layouts 1.6
import QtQml.Models 2.1
import 'util.js' as Util
ListView {
id: control
required property var tags // tag definitions
property bool editing: false
property var tags: []
signal changed
clip: true
focus: true
keyNavigationEnabled: true
highlightMoveDuration: 0
highlightResizeDuration: 0
ScrollBar.vertical: ScrollBar { anchors.right: parent.right }
// Create a new blank event, insert it and start editing.
function create(time, tag, fields) {
const index = Util.find(list, 'time', time)
list.insert(index, {
'time': time,
'tag': tag,
'fields': fields,
})
currentIndex = index
if (fields.length > 0)
editing = true
changed()
}
function clear() {
list.clear()
}
function load(json) {
// Return list of fields for the given tag.
function getFields(name) {
for (var i = 0; i < tags.length; i++)
if (tags[i].tag === name)
return tags[i].fields
return []
}
for (var i = 0; i < json.length; i++) {
const event = json[i]
var fields = getFields(event.tag)
for (var j = 0; j < fields.length; j++)
fields[j].value = event.fields[fields[j].name]
list.append({ 'time': event.time, 'tag': event.tag, 'fields': fields })
}
forceActiveFocus()
}
function save() {
var data = []
for (var i = 0; i < list.count; i++) {
const event = list.get(i)
var fields = {}
for (var j = 0; j < event.fields.count; j++) {
const field = event.fields.get(j)
fields[field.name] = field.value
}
data.push({ 'time': event.time, 'tag': event.tag, 'fields': fields })
}
return data
}
onCurrentIndexChanged: editing = false
Keys.onPressed: {
switch (event.key) {
case Qt.Key_Enter:
case Qt.Key_Return:
if (editing) {
currentItem.store()
changed()
editing = false
} else {
if (currentItem.fields.count > 0)
editing = true
}
break
case Qt.Key_Escape:
if (editing) {
currentItem.reset()
editing = false
}
break
case Qt.Key_Delete:
editing = false
if (currentIndex >= 0 && currentIndex < list.count) {
list.remove(currentIndex)
changed()
}
break
case Qt.Key_Tab:
case Qt.Key_Backtab:
// swallow tabs so we dont lose focus when editing
break
default:
return
}
event.accepted = true
}
model: ListModel {
id: list
dynamicRoles: true
}
ScrollBar.vertical: ScrollBar { anchors.right: parent.right }
delegate: Event {
id: item
time: model.time
tag: model.tag
fields: model.fields
// If field definitions are missing for this events tag, use
// Text for all field types unless where the value is bool.
fields: tags[model.tag] ? tags[model.tag].fields :
Object.entries(model.values).map(value => ({
'name': value[0],
'type': typeof(value[1]) === 'boolean' ? 'Bool' : 'Text',
}))
width: control.width
editing: control.editing && ListView.isCurrentItem
background: Rectangle {
anchors.fill: parent
color: border.width > 0 ? Util.alphize(border.color, 0.1) :
(index % 2 === 0 ? palette.base : palette.alternateBase)
border {
color: editing ? palette.highlight : palette.dark
width: item.ListView.isCurrentItem ? 1 : 0
}
radius: border.width
}
highlighted: ListView.isCurrentItem
Connections {
enabled: ListView.currentIndex === index
@ -143,13 +39,10 @@ ListView {
control.positionViewAtIndex(index, ListView.Contain)
}
}
onEditingChanged: {
reset()
if (editing)
forceActiveFocus()
}
onRemove: {
list.remove(ObjectModel.index)
onClicked: {
control.currentIndex = index
control.forceActiveFocus()
}
}
}