[Editor] Enable gathering Game logs in Process Logs View

This commit is contained in:
2021-02-26 19:56:25 +01:00
parent 1c25be3eb5
commit 290090c4d3
7 changed files with 95 additions and 9 deletions

View File

@@ -15,11 +15,13 @@ class BuildLogsView : View() {
private val projectContext: ProjectContext by di() private val projectContext: ProjectContext by di()
private val mainController: MainController by di() private val mainController: MainController by di()
private val followCaret = true.toProperty()
private val buildLogs = LogsPane(this::locationClick) private val buildLogs = LogsPane(this::locationClick)
init { init {
subscribe<AppendBuildLogsEvent> { event -> subscribe<AppendBuildLogsEvent> { event ->
buildLogs.appendEntry(event.message, event.severity, event.location, event.tag) buildLogs.appendEntry(event.message, event.severity, followCaret.value, event.location, event.tag)
} }
subscribe<ClearBuildLogsEvent> { subscribe<ClearBuildLogsEvent> {
@@ -34,10 +36,15 @@ class BuildLogsView : View() {
} }
override val root = borderpane { override val root = borderpane {
left = hbox { left = vbox {
button(graphic = FontIcon("fa-trash")) { button(graphic = FontIcon("fa-trash")) {
action { buildLogs.clear() } action { buildLogs.clear() }
} }
togglebutton {
followCaret.bind(selectedProperty())
graphic = FontIcon("fa-angle-double-down")
}
} }
center = buildLogs center = buildLogs

View File

@@ -8,7 +8,7 @@ import org.codehaus.commons.compiler.Location
import org.fxmisc.richtext.StyledTextArea import org.fxmisc.richtext.StyledTextArea
import tornadofx.addClass import tornadofx.addClass
class LogsPane(private val locationClick: (location: Location) -> Unit) : StackPane() { class LogsPane(private val locationClick: (location: Location) -> Unit = {}) : StackPane() {
private val editor = StyledTextArea("logs-pane", private val editor = StyledTextArea("logs-pane",
{ text, style -> text.addClass(style) }, { text, style -> text.addClass(style) },
LogsPaneStyle.NO_STYLE, LogsPaneStyle.NO_STYLE,
@@ -19,7 +19,13 @@ class LogsPane(private val locationClick: (location: Location) -> Unit) : StackP
children += editor children += editor
} }
fun appendEntry(message: String, severity: Severity, location: Location?, tag: String?) { fun appendEntry(
message: String,
severity: Severity,
follow: Boolean,
location: Location? = null,
tag: String? = null
) {
val locationRef = LogsPaneStyle(location = location, onClick = locationClick) val locationRef = LogsPaneStyle(location = location, onClick = locationClick)
val severityStyle = LogsPaneStyle(severity = severity) val severityStyle = LogsPaneStyle(severity = severity)
@@ -27,6 +33,10 @@ class LogsPane(private val locationClick: (location: Location) -> Unit) : StackP
editor.insert(editor.length, location?.toString() ?: "", locationRef) editor.insert(editor.length, location?.toString() ?: "", locationRef)
editor.insert(editor.length, (location?.let { ": " } ?: "") + message, LogsPaneStyle(severity = severity)) editor.insert(editor.length, (location?.let { ": " } ?: "") + message, LogsPaneStyle(severity = severity))
editor.insert(editor.length, "\n", LogsPaneStyle.NO_STYLE) editor.insert(editor.length, "\n", LogsPaneStyle.NO_STYLE)
if (follow) {
editor.requestFollowCaret()
}
} }
fun clear() = editor.clear() fun clear() = editor.clear()

View File

@@ -0,0 +1,8 @@
package com.bartlomiejpluta.base.editor.event
import com.bartlomiejpluta.base.editor.common.logs.enumeration.Severity
import tornadofx.EventBus
import tornadofx.FXEvent
data class AppendProcessLogsEvent(val severity: Severity, val message: String) :
FXEvent(EventBus.RunOn.ApplicationThread)

View File

@@ -0,0 +1,6 @@
package com.bartlomiejpluta.base.editor.event
import tornadofx.EventBus
import tornadofx.FXEvent
object ClearProcessLogsEvent : FXEvent(EventBus.RunOn.ApplicationThread)

View File

@@ -7,11 +7,13 @@ import com.bartlomiejpluta.base.editor.code.view.CodeEditorFragment
import com.bartlomiejpluta.base.editor.code.view.ScriptFilesView import com.bartlomiejpluta.base.editor.code.view.ScriptFilesView
import com.bartlomiejpluta.base.editor.code.viewmodel.CodeVM import com.bartlomiejpluta.base.editor.code.viewmodel.CodeVM
import com.bartlomiejpluta.base.editor.event.AppendBuildLogsEvent import com.bartlomiejpluta.base.editor.event.AppendBuildLogsEvent
import com.bartlomiejpluta.base.editor.event.AppendProcessLogsEvent
import com.bartlomiejpluta.base.editor.event.SelectMainViewTabEvent import com.bartlomiejpluta.base.editor.event.SelectMainViewTabEvent
import com.bartlomiejpluta.base.editor.main.controller.MainController import com.bartlomiejpluta.base.editor.main.controller.MainController
import com.bartlomiejpluta.base.editor.map.model.map.GameMap import com.bartlomiejpluta.base.editor.map.model.map.GameMap
import com.bartlomiejpluta.base.editor.map.view.editor.MapFragment import com.bartlomiejpluta.base.editor.map.view.editor.MapFragment
import com.bartlomiejpluta.base.editor.map.viewmodel.GameMapVM import com.bartlomiejpluta.base.editor.map.viewmodel.GameMapVM
import com.bartlomiejpluta.base.editor.process.view.ProcessLogsView
import com.bartlomiejpluta.base.editor.project.context.ProjectContext import com.bartlomiejpluta.base.editor.project.context.ProjectContext
import javafx.collections.MapChangeListener import javafx.collections.MapChangeListener
import javafx.event.Event import javafx.event.Event
@@ -28,10 +30,12 @@ class MainView : View("BASE Game Editor") {
private val assetsView = find<AssetsListView>() private val assetsView = find<AssetsListView>()
private val scriptFilesView = find<ScriptFilesView>() private val scriptFilesView = find<ScriptFilesView>()
private val buildLogsView = find<BuildLogsView>() private val buildLogsView = find<BuildLogsView>()
private val processLogsView = find<ProcessLogsView>()
private val openTabs = mutableMapOf<Scope, Tab>() private val openTabs = mutableMapOf<Scope, Tab>()
private var buildLogItem: DrawerItem by singleAssign() private var buildLogItem: DrawerItem by singleAssign()
private var processLogItem: DrawerItem by singleAssign()
private val tabPane = tabpane { private val tabPane = tabpane {
@@ -82,6 +86,10 @@ class MainView : View("BASE Game Editor") {
buildLogItem.expanded = true buildLogItem.expanded = true
} }
subscribe<AppendProcessLogsEvent> {
processLogItem.expanded = true
}
subscribe<SelectMainViewTabEvent> { event -> subscribe<SelectMainViewTabEvent> { event ->
openTabs[event.targetScope]?.let { openTabs[event.targetScope]?.let {
tabPane.selectionModel.select(it) tabPane.selectionModel.select(it)
@@ -104,10 +112,14 @@ class MainView : View("BASE Game Editor") {
} }
} }
bottom = drawer(multiselect = true) { bottom = drawer {
buildLogItem = item("Build Log") { buildLogItem = item("Build Log") {
this += buildLogsView this += buildLogsView
} }
processLogItem = item("Process Log") {
this += processLogsView
}
} }
} }

View File

@@ -1,12 +1,16 @@
package com.bartlomiejpluta.base.editor.process.runner.app package com.bartlomiejpluta.base.editor.process.runner.app
import com.bartlomiejpluta.base.editor.code.build.pipeline.BuildPipelineService import com.bartlomiejpluta.base.editor.code.build.pipeline.BuildPipelineService
import com.bartlomiejpluta.base.editor.common.logs.enumeration.Severity
import com.bartlomiejpluta.base.editor.event.AppendProcessLogsEvent
import com.bartlomiejpluta.base.editor.event.ClearProcessLogsEvent
import com.bartlomiejpluta.base.editor.process.runner.jar.JarRunner import com.bartlomiejpluta.base.editor.process.runner.jar.JarRunner
import com.bartlomiejpluta.base.editor.project.context.ProjectContext import com.bartlomiejpluta.base.editor.project.context.ProjectContext
import com.bartlomiejpluta.base.editor.project.model.Project import com.bartlomiejpluta.base.editor.project.model.Project
import javafx.event.EventHandler import javafx.event.EventHandler
import org.springframework.beans.factory.annotation.Autowired import org.springframework.beans.factory.annotation.Autowired
import org.springframework.stereotype.Component import org.springframework.stereotype.Component
import tornadofx.FX.Companion.eventbus
import tornadofx.getValue import tornadofx.getValue
import tornadofx.runAsync import tornadofx.runAsync
import tornadofx.setValue import tornadofx.setValue
@@ -39,25 +43,26 @@ class DefaultApplicationRunner : ApplicationRunner {
} }
private fun runApplication(project: Project) { private fun runApplication(project: Project) {
eventbus.fire(ClearProcessLogsEvent)
val builder = jarRunner.run(project.buildOutputJarFile) val builder = jarRunner.run(project.buildOutputJarFile)
val process = builder.start() val process = builder.start()
runAsync { runAsync {
process.inputStream.bufferedReader().forEachLine { process.inputStream.bufferedReader().forEachLine {
println("OUTPUT -> $it") eventbus.fire(AppendProcessLogsEvent(Severity.INFO, it))
} }
} }
runAsync { runAsync {
process.errorStream.bufferedReader().forEachLine { process.errorStream.bufferedReader().forEachLine {
println("ERROR -> $it") eventbus.fire(AppendProcessLogsEvent(Severity.ERROR, it))
} }
} }
process.onExit().thenApply { process.onExit().thenApply {
println("EXIT WITH ${it.exitValue()}") eventbus.fire(AppendProcessLogsEvent(Severity.INFO, "\nProcess exited with code ${it.exitValue()}"))
isRunning = false isRunning = false
} }
} }
} }

View File

@@ -0,0 +1,38 @@
package com.bartlomiejpluta.base.editor.process.view
import com.bartlomiejpluta.base.editor.common.logs.component.LogsPane
import com.bartlomiejpluta.base.editor.event.AppendProcessLogsEvent
import com.bartlomiejpluta.base.editor.event.ClearProcessLogsEvent
import org.kordamp.ikonli.javafx.FontIcon
import tornadofx.*
class ProcessLogsView : View() {
private val buildLogs = LogsPane()
private val followCaret = true.toProperty()
init {
subscribe<AppendProcessLogsEvent> { event ->
buildLogs.appendEntry(event.message, event.severity, followCaret.value)
}
subscribe<ClearProcessLogsEvent> {
buildLogs.clear()
}
}
override val root = borderpane {
left = vbox {
button(graphic = FontIcon("fa-trash")) {
action { buildLogs.clear() }
}
togglebutton {
followCaret.bind(selectedProperty())
graphic = FontIcon("fa-angle-double-down")
}
}
center = buildLogs
}
}