[Editor] Add support for in-memory executable scripts
This commit is contained in:
@@ -6,7 +6,13 @@ import tornadofx.getValue
|
|||||||
import tornadofx.setValue
|
import tornadofx.setValue
|
||||||
import tornadofx.toProperty
|
import tornadofx.toProperty
|
||||||
|
|
||||||
class Code(fileNode: FileNode, val typeProperty: Property<CodeType>, code: String) {
|
class Code(
|
||||||
|
fileNode: FileNode,
|
||||||
|
val typeProperty: Property<CodeType>,
|
||||||
|
code: String,
|
||||||
|
saveable: Boolean = true,
|
||||||
|
execute: ((String) -> Unit)? = null
|
||||||
|
) {
|
||||||
val fileNodeProperty = fileNode.toProperty()
|
val fileNodeProperty = fileNode.toProperty()
|
||||||
val fileNode by fileNodeProperty
|
val fileNode by fileNodeProperty
|
||||||
|
|
||||||
@@ -14,4 +20,13 @@ class Code(fileNode: FileNode, val typeProperty: Property<CodeType>, code: Strin
|
|||||||
|
|
||||||
val codeProperty = code.toProperty()
|
val codeProperty = code.toProperty()
|
||||||
var code by codeProperty
|
var code by codeProperty
|
||||||
|
|
||||||
|
val saveableProperty = saveable.toProperty()
|
||||||
|
val saveable by saveableProperty
|
||||||
|
|
||||||
|
val executeProperty = execute.toProperty()
|
||||||
|
|
||||||
|
fun execute() {
|
||||||
|
executeProperty.value?.let { it(code) }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -7,6 +7,7 @@ import com.bartlomiejpluta.base.editor.code.model.CodeScope
|
|||||||
import com.bartlomiejpluta.base.editor.code.model.CodeType
|
import com.bartlomiejpluta.base.editor.code.model.CodeType
|
||||||
import com.bartlomiejpluta.base.editor.code.viewmodel.CodeVM
|
import com.bartlomiejpluta.base.editor.code.viewmodel.CodeVM
|
||||||
import com.bartlomiejpluta.base.editor.file.model.FileSystemNode
|
import com.bartlomiejpluta.base.editor.file.model.FileSystemNode
|
||||||
|
import com.bartlomiejpluta.base.editor.file.model.InMemoryStringFileNode
|
||||||
import com.bartlomiejpluta.base.editor.file.model.ScriptAssetFileNode
|
import com.bartlomiejpluta.base.editor.file.model.ScriptAssetFileNode
|
||||||
import com.bartlomiejpluta.base.editor.project.context.ProjectContext
|
import com.bartlomiejpluta.base.editor.project.context.ProjectContext
|
||||||
import javafx.beans.binding.Bindings
|
import javafx.beans.binding.Bindings
|
||||||
@@ -31,7 +32,7 @@ class CodeEditorView : View() {
|
|||||||
}, codeVM.typeProperty)
|
}, codeVM.typeProperty)
|
||||||
|
|
||||||
private val editable = Bindings.createBooleanBinding(
|
private val editable = Bindings.createBooleanBinding(
|
||||||
{ codeVM.fileNode is FileSystemNode || codeVM.fileNode is ScriptAssetFileNode },
|
{ codeVM.fileNode is FileSystemNode || codeVM.fileNode is ScriptAssetFileNode || codeVM.fileNode is InMemoryStringFileNode },
|
||||||
codeVM.itemProperty
|
codeVM.itemProperty
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -50,10 +51,13 @@ class CodeEditorView : View() {
|
|||||||
|
|
||||||
override val root = borderpane {
|
override val root = borderpane {
|
||||||
top = toolbar {
|
top = toolbar {
|
||||||
|
|
||||||
|
if (codeVM.saveable && editable.value) {
|
||||||
button(graphic = FontIcon("fa-floppy-o")) {
|
button(graphic = FontIcon("fa-floppy-o")) {
|
||||||
enableWhen(codeVM.dirty.and(editable))
|
enableWhen(codeVM.dirty)
|
||||||
action { save() }
|
action { save() }
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
button(graphic = FontIcon("fa-undo")) {
|
button(graphic = FontIcon("fa-undo")) {
|
||||||
enableWhen(editable)
|
enableWhen(editable)
|
||||||
@@ -64,6 +68,12 @@ class CodeEditorView : View() {
|
|||||||
enableWhen(editable)
|
enableWhen(editable)
|
||||||
action { redo() }
|
action { redo() }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (codeVM.executeProperty.isNotNull.value) {
|
||||||
|
button(graphic = FontIcon("fa-play")) {
|
||||||
|
action { execute() }
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
center = editor
|
center = editor
|
||||||
@@ -73,8 +83,13 @@ class CodeEditorView : View() {
|
|||||||
|
|
||||||
fun undo() = editor.undo()
|
fun undo() = editor.undo()
|
||||||
|
|
||||||
fun save() = codeVM.item?.let {
|
fun save() = codeVM.takeIf { editable.value && it.saveable }?.item?.let {
|
||||||
codeVM.commit(codeVM.codeProperty)
|
codeVM.commit(codeVM.codeProperty)
|
||||||
projectContext.saveScript(it)
|
projectContext.saveScript(it)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun execute() {
|
||||||
|
codeVM.commit(codeVM.codeProperty)
|
||||||
|
codeVM.execute()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -14,4 +14,13 @@ class CodeVM(code: Code) : ItemViewModel<Code>(code) {
|
|||||||
|
|
||||||
val codeProperty = bind(Code::codeProperty)
|
val codeProperty = bind(Code::codeProperty)
|
||||||
var code by codeProperty
|
var code by codeProperty
|
||||||
|
|
||||||
|
val saveableProperty = bind(Code::saveableProperty)
|
||||||
|
val saveable by saveableProperty
|
||||||
|
|
||||||
|
val executeProperty = bind(Code::executeProperty)
|
||||||
|
|
||||||
|
fun execute() {
|
||||||
|
item?.execute()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
package com.bartlomiejpluta.base.editor.file.model
|
||||||
|
|
||||||
|
import javafx.beans.property.SimpleLongProperty
|
||||||
|
import tornadofx.getValue
|
||||||
|
import tornadofx.toProperty
|
||||||
|
|
||||||
|
class InMemoryStringFileNode(name: String, extension: String, val content: String) : FileNode {
|
||||||
|
override val nameProperty = "$name.$extension".toProperty()
|
||||||
|
override val name by nameProperty
|
||||||
|
|
||||||
|
override val extensionProperty = extension.toProperty()
|
||||||
|
override val extension by extensionProperty
|
||||||
|
|
||||||
|
override val nameWithoutExtensionProperty = name.toProperty()
|
||||||
|
override val nameWithoutExtension by nameWithoutExtensionProperty
|
||||||
|
|
||||||
|
override val absolutePathProperty = "".toProperty()
|
||||||
|
override val absolutePath by absolutePathProperty
|
||||||
|
|
||||||
|
override val type = FileType.FILE
|
||||||
|
|
||||||
|
override val parent = null
|
||||||
|
|
||||||
|
override val children = emptyList<FileNode>()
|
||||||
|
|
||||||
|
override val lastModifiedProperty = SimpleLongProperty(0)
|
||||||
|
override val lastModified by lastModifiedProperty
|
||||||
|
|
||||||
|
override fun inputStream() = content.byteInputStream()
|
||||||
|
}
|
||||||
@@ -98,12 +98,18 @@ class MainController : Controller() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun openScript(fsNode: FileNode, line: Int = 1, column: Int = 1) {
|
fun openScript(
|
||||||
|
fsNode: FileNode,
|
||||||
|
line: Int = 1,
|
||||||
|
column: Int = 1,
|
||||||
|
execute: ((String) -> Unit)? = null,
|
||||||
|
saveable: Boolean = true
|
||||||
|
) {
|
||||||
val findScript = { script: Code -> script.fileNode.absolutePath == fsNode.absolutePath }
|
val findScript = { script: Code -> script.fileNode.absolutePath == fsNode.absolutePath }
|
||||||
val updateExistingScope = { scope: CodeScope -> scope.setCaretPosition(line, column) }
|
val updateExistingScope = { scope: CodeScope -> scope.setCaretPosition(line, column) }
|
||||||
|
|
||||||
openItem(findScript, updateExistingScope) {
|
openItem(findScript, updateExistingScope) {
|
||||||
val code = projectContext.loadScript(fsNode)
|
val code = projectContext.loadScript(fsNode, execute, saveable)
|
||||||
val vm = CodeVM(code)
|
val vm = CodeVM(code)
|
||||||
val scope = CodeScope(line, column)
|
val scope = CodeScope(line, column)
|
||||||
setInScope(vm, scope)
|
setInScope(vm, scope)
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import com.bartlomiejpluta.base.editor.code.view.build.BuildLogsView
|
|||||||
import com.bartlomiejpluta.base.editor.code.view.editor.CodeEditorFragment
|
import com.bartlomiejpluta.base.editor.code.view.editor.CodeEditorFragment
|
||||||
import com.bartlomiejpluta.base.editor.code.view.list.ScriptFilesView
|
import com.bartlomiejpluta.base.editor.code.view.list.ScriptFilesView
|
||||||
import com.bartlomiejpluta.base.editor.code.viewmodel.CodeVM
|
import com.bartlomiejpluta.base.editor.code.viewmodel.CodeVM
|
||||||
|
import com.bartlomiejpluta.base.editor.database.view.list.TablesListView
|
||||||
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.AppendProcessLogsEvent
|
||||||
import com.bartlomiejpluta.base.editor.event.SelectMainViewTabEvent
|
import com.bartlomiejpluta.base.editor.event.SelectMainViewTabEvent
|
||||||
@@ -36,6 +37,7 @@ class MainView : View("BASE Game Editor") {
|
|||||||
private val buildLogsView = find<BuildLogsView>()
|
private val buildLogsView = find<BuildLogsView>()
|
||||||
private val processLogsView = find<ProcessLogsView>()
|
private val processLogsView = find<ProcessLogsView>()
|
||||||
private val projectPropertiesView = find<ProjectParametersView>()
|
private val projectPropertiesView = find<ProjectParametersView>()
|
||||||
|
private val databaseTablesListView = find<TablesListView>()
|
||||||
|
|
||||||
private val openTabs = mutableMapOf<Scope, Tab>()
|
private val openTabs = mutableMapOf<Scope, Tab>()
|
||||||
|
|
||||||
@@ -123,6 +125,10 @@ class MainView : View("BASE Game Editor") {
|
|||||||
this += assetsView
|
this += assetsView
|
||||||
}
|
}
|
||||||
|
|
||||||
|
item("Database", expanded = false) {
|
||||||
|
this += databaseTablesListView
|
||||||
|
}
|
||||||
|
|
||||||
item("Project Parameters") {
|
item("Project Parameters") {
|
||||||
enableWhen(projectContext.projectProperty.isNotNull)
|
enableWhen(projectContext.projectProperty.isNotNull)
|
||||||
this += projectPropertiesView
|
this += projectPropertiesView
|
||||||
|
|||||||
@@ -247,7 +247,7 @@ class DefaultProjectContext : ProjectContext {
|
|||||||
} ?: throw IllegalStateException("There is no open project in the context")
|
} ?: throw IllegalStateException("There is no open project in the context")
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun loadScript(fileNode: FileNode): Code {
|
override fun loadScript(fileNode: FileNode, execute: ((String) -> Unit)?, saveable: Boolean): Code {
|
||||||
val typeProperty = SimpleObjectProperty<CodeType>().apply {
|
val typeProperty = SimpleObjectProperty<CodeType>().apply {
|
||||||
bind(createObjectBinding({
|
bind(createObjectBinding({
|
||||||
when (fileNode.extension.toLowerCase()) {
|
when (fileNode.extension.toLowerCase()) {
|
||||||
@@ -261,7 +261,7 @@ class DefaultProjectContext : ProjectContext {
|
|||||||
|
|
||||||
val code = fileNode.readText()
|
val code = fileNode.readText()
|
||||||
|
|
||||||
return Code(fileNode, typeProperty, code)
|
return Code(fileNode, typeProperty, code, saveable, execute)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun saveScript(code: Code) {
|
override fun saveScript(code: Code) {
|
||||||
|
|||||||
@@ -49,6 +49,6 @@ interface ProjectContext {
|
|||||||
fun importSound(data: SoundAssetData)
|
fun importSound(data: SoundAssetData)
|
||||||
|
|
||||||
fun deleteAsset(asset: Asset)
|
fun deleteAsset(asset: Asset)
|
||||||
fun loadScript(fileNode: FileNode): Code
|
fun loadScript(fileNode: FileNode, execute: ((String) -> Unit)?, saveable: Boolean): Code
|
||||||
fun saveScript(code: Code)
|
fun saveScript(code: Code)
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user