worked on better integrating existing code w Godot
This commit is contained in:
parent
7822c7e6b0
commit
13d2391e57
|
@ -18,7 +18,9 @@ signal finished
|
||||||
|
|
||||||
const Constants = preload('res://addons/Wol/core/constants.gd')
|
const Constants = preload('res://addons/Wol/core/constants.gd')
|
||||||
const WolCompiler = preload('res://addons/Wol/core/compiler/compiler.gd')
|
const WolCompiler = preload('res://addons/Wol/core/compiler/compiler.gd')
|
||||||
const WolDialogue = preload('res://addons/Wol/core/dialogue.gd')
|
const WolLibrary = preload('res://addons/Wol/core/library.gd')
|
||||||
|
const VirtualMachine = preload('res://addons/Wol/core/virtual_machine.gd')
|
||||||
|
const StandardLibrary = preload('res://addons/Wol/core/StandardLibrary.gd')
|
||||||
|
|
||||||
export(String, FILE, '*.wol,*.yarn') var path setget set_path
|
export(String, FILE, '*.wol,*.yarn') var path setget set_path
|
||||||
export(String) var start_node = 'Start'
|
export(String) var start_node = 'Start'
|
||||||
|
@ -28,14 +30,18 @@ export var auto_show_options = true
|
||||||
|
|
||||||
onready var variable_storage = get_node(variable_storage_path)
|
onready var variable_storage = get_node(variable_storage_path)
|
||||||
|
|
||||||
var program
|
var virtual_machine
|
||||||
|
|
||||||
var dialogue
|
|
||||||
|
|
||||||
func _ready():
|
func _ready():
|
||||||
if Engine.editor_hint:
|
if Engine.editor_hint:
|
||||||
return
|
return
|
||||||
|
|
||||||
|
var libraries = WolLibrary.new()
|
||||||
|
libraries.import_library(StandardLibrary.new())
|
||||||
|
virtual_machine = VirtualMachine.new(self, libraries)
|
||||||
|
|
||||||
|
set_path(path)
|
||||||
|
|
||||||
if not variable_storage:
|
if not variable_storage:
|
||||||
variable_storage = Node.new()
|
variable_storage = Node.new()
|
||||||
variable_storage.name = 'VariableStorage'
|
variable_storage.name = 'VariableStorage'
|
||||||
|
@ -45,43 +51,22 @@ func _ready():
|
||||||
if auto_start:
|
if auto_start:
|
||||||
start()
|
start()
|
||||||
|
|
||||||
func init_dialogue():
|
|
||||||
# FIXME: Move visited count to variable storage
|
|
||||||
var existing_state
|
|
||||||
if dialogue != null:
|
|
||||||
existing_state = dialogue._visitedNodeCount
|
|
||||||
|
|
||||||
dialogue = WolDialogue.new(variable_storage)
|
|
||||||
|
|
||||||
# FIXME: Remove these lines
|
|
||||||
if existing_state:
|
|
||||||
dialogue._visitedNodeCount = existing_state
|
|
||||||
|
|
||||||
dialogue.get_vm().lineHandler = funcref(self, '_handle_line')
|
|
||||||
dialogue.get_vm().optionsHandler = funcref(self, '_handle_options')
|
|
||||||
dialogue.get_vm().commandHandler = funcref(self, '_handle_command')
|
|
||||||
dialogue.get_vm().nodeCompleteHandler = funcref(self, '_handle_node_complete')
|
|
||||||
dialogue.get_vm().dialogueCompleteHandler = funcref(self, '_handle_dialogue_complete')
|
|
||||||
dialogue.get_vm().nodeStartHandler = funcref(self, '_handle_node_start')
|
|
||||||
|
|
||||||
dialogue.set_program(program)
|
|
||||||
|
|
||||||
func set_path(_path):
|
func set_path(_path):
|
||||||
path = _path
|
path = _path
|
||||||
|
|
||||||
if not Engine.editor_hint:
|
if not Engine.editor_hint and virtual_machine:
|
||||||
var compiler = WolCompiler.new(path)
|
var compiler = WolCompiler.new(path)
|
||||||
program = compiler.compile()
|
virtual_machine.program = compiler.compile()
|
||||||
|
|
||||||
func _handle_line(line):
|
func _on_line(line):
|
||||||
call_deferred('emit_signal', 'line', line)
|
call_deferred('emit_signal', 'line', line)
|
||||||
if auto_show_options \
|
if auto_show_options \
|
||||||
and dialogue.get_vm().get_next_instruction().operation == Constants.ByteCode.AddOption:
|
and virtual_machine.get_next_instruction().operation == Constants.ByteCode.AddOption:
|
||||||
return Constants.HandlerState.ContinueExecution
|
return Constants.HandlerState.ContinueExecution
|
||||||
else:
|
else:
|
||||||
return Constants.HandlerState.PauseExecution
|
return Constants.HandlerState.PauseExecution
|
||||||
|
|
||||||
func _handle_command(command):
|
func _on_command(command):
|
||||||
call_deferred('emit_signal', 'command', command)
|
call_deferred('emit_signal', 'command', command)
|
||||||
|
|
||||||
if get_signal_connection_list('command').size() > 0:
|
if get_signal_connection_list('command').size() > 0:
|
||||||
|
@ -89,39 +74,33 @@ func _handle_command(command):
|
||||||
else:
|
else:
|
||||||
return Constants.HandlerState.ContinueExecution
|
return Constants.HandlerState.ContinueExecution
|
||||||
|
|
||||||
func _handle_options(options):
|
func _on_options(options):
|
||||||
call_deferred('emit_signal', 'options', options)
|
call_deferred('emit_signal', 'options', options)
|
||||||
return Constants.HandlerState.PauseExecution
|
return Constants.HandlerState.PauseExecution
|
||||||
|
|
||||||
func _handle_dialogue_complete():
|
func _on_dialogue_finished():
|
||||||
emit_signal('finished')
|
emit_signal('finished')
|
||||||
|
|
||||||
func _handle_node_start(node):
|
func _on_node_start(node):
|
||||||
emit_signal('node_started', node)
|
emit_signal('node_started', node)
|
||||||
dialogue.resume()
|
resume()
|
||||||
|
|
||||||
if !dialogue._visitedNodeCount.has(node):
|
func _on_node_finished(node):
|
||||||
dialogue._visitedNodeCount[node] = 1
|
|
||||||
else:
|
|
||||||
dialogue._visitedNodeCount[node] += 1
|
|
||||||
|
|
||||||
func _handle_node_complete(node):
|
|
||||||
emit_signal('node_finished', node)
|
emit_signal('node_finished', node)
|
||||||
return Constants.HandlerState.ContinueExecution
|
return Constants.HandlerState.ContinueExecution
|
||||||
|
|
||||||
func select_option(id):
|
func select_option(id):
|
||||||
dialogue.get_vm().set_selected_option(id)
|
virtual_machine.set_selected_option(id)
|
||||||
resume()
|
resume()
|
||||||
|
|
||||||
func pause():
|
func pause():
|
||||||
dialogue.call_deferred('pause')
|
virtual_machine.call_deferred('pause')
|
||||||
|
|
||||||
func start(node = start_node):
|
func start(node = start_node):
|
||||||
init_dialogue()
|
|
||||||
emit_signal('started')
|
emit_signal('started')
|
||||||
|
|
||||||
dialogue.set_node(node)
|
virtual_machine.set_node(node)
|
||||||
dialogue.start()
|
virtual_machine.resume()
|
||||||
|
|
||||||
func resume():
|
func resume():
|
||||||
dialogue.call_deferred('resume')
|
virtual_machine.call_deferred('resume')
|
||||||
|
|
96
addons/Wol/core/StandardLibrary.gd
Normal file
96
addons/Wol/core/StandardLibrary.gd
Normal file
|
@ -0,0 +1,96 @@
|
||||||
|
extends 'res://addons/Wol/core/library.gd'
|
||||||
|
|
||||||
|
const Value = preload('res://addons/Wol/core/value.gd')
|
||||||
|
|
||||||
|
func _init():
|
||||||
|
register_function('Add', 2, funcref(self, 'add'), true)
|
||||||
|
register_function('Minus', 2, funcref(self, 'sub'), true)
|
||||||
|
register_function('UnaryMinus', 1, funcref(self, 'unary_minus'), true)
|
||||||
|
register_function('Divide', 2, funcref(self, 'div'), true)
|
||||||
|
register_function('Multiply', 2, funcref(self, 'mul'), true)
|
||||||
|
register_function('Modulo', 2, funcref(self, 'mod'), true)
|
||||||
|
register_function('EqualTo', 2, funcref(self, 'equal'), true)
|
||||||
|
register_function('NotEqualTo', 2, funcref(self, 'noteq'), true)
|
||||||
|
register_function('GreaterThan', 2, funcref(self, 'ge'), true)
|
||||||
|
register_function('GreaterThanOrEqualTo', 2, funcref(self, 'geq'), true)
|
||||||
|
register_function('LessThan', 2, funcref(self, 'le'), true)
|
||||||
|
register_function('LessThanOrEqualTo', 2, funcref(self, 'leq'), true)
|
||||||
|
register_function('And', 2, funcref(self, 'land'), true)
|
||||||
|
register_function('Or', 2, funcref(self, 'lor'), true)
|
||||||
|
register_function('Xor', 2, funcref(self, 'xor'), true)
|
||||||
|
register_function('Not', 1, funcref(self, 'lnot'), true)
|
||||||
|
|
||||||
|
# `visited` and `visit_count` functions
|
||||||
|
register_function('visited', -1, funcref(self, 'is_node_visited'), true)
|
||||||
|
register_function('visit_count', -1, funcref(self, 'node_visit_count'), true)
|
||||||
|
|
||||||
|
|
||||||
|
func add(param1, param2):
|
||||||
|
return param1.add(param2)
|
||||||
|
|
||||||
|
func sub(param1, param2):
|
||||||
|
return param1.sub(param2)
|
||||||
|
|
||||||
|
func unary_minus(param1):
|
||||||
|
return param1.negative()
|
||||||
|
|
||||||
|
func div(param1, param2):
|
||||||
|
return param1.div(param2)
|
||||||
|
|
||||||
|
func mul(param1, param2):
|
||||||
|
return param1.mult(param2)
|
||||||
|
func mod(param1, param2):
|
||||||
|
return param1.mod(param2)
|
||||||
|
|
||||||
|
func equal(param1, param2):
|
||||||
|
return param1.equals(param2)
|
||||||
|
|
||||||
|
func noteq(param1, param2):
|
||||||
|
return !param1.equals(param2)
|
||||||
|
|
||||||
|
func ge(param1, param2):
|
||||||
|
return param1.greater(param2)
|
||||||
|
|
||||||
|
func geq(param1, param2):
|
||||||
|
return param1.geq(param2)
|
||||||
|
|
||||||
|
func le(param1, param2):
|
||||||
|
return param1.less(param2)
|
||||||
|
|
||||||
|
func leq(param1, param2):
|
||||||
|
return param1.leq(param2)
|
||||||
|
|
||||||
|
func land(param1, param2):
|
||||||
|
return param1.as_bool() and param2.as_bool()
|
||||||
|
|
||||||
|
func lor(param1, param2):
|
||||||
|
return param1.as_bool() or param2.as_bool()
|
||||||
|
|
||||||
|
func xor(param1, param2):
|
||||||
|
return param1.as_bool() != param2.as_bool()
|
||||||
|
|
||||||
|
func lnot(param1):
|
||||||
|
return not param1.as_bool()
|
||||||
|
|
||||||
|
var visited_node_count = {}
|
||||||
|
|
||||||
|
func is_node_visited(node = virtual_machine.current_node_name()):
|
||||||
|
return node_visit_count(node) > 0
|
||||||
|
|
||||||
|
func node_visit_count(node = virtual_machine.current_node_name()):
|
||||||
|
if node is Value:
|
||||||
|
node = virtual_machine.program.strings[node.value()].text
|
||||||
|
|
||||||
|
var visit_count = 0
|
||||||
|
if visited_node_count.has(node):
|
||||||
|
visit_count = visited_node_count[node]
|
||||||
|
|
||||||
|
return visit_count
|
||||||
|
|
||||||
|
func get_visited_nodes():
|
||||||
|
return visited_node_count.keys()
|
||||||
|
|
||||||
|
func set_visited_nodes(visitedList):
|
||||||
|
visited_node_count.clear()
|
||||||
|
for string in visitedList:
|
||||||
|
visited_node_count[string] = 1
|
|
@ -1,11 +1,7 @@
|
||||||
extends Node
|
extends Node
|
||||||
|
|
||||||
const DEFAULT_START = 'Start'
|
|
||||||
|
|
||||||
const Constants = preload('res://addons/Wol/core/constants.gd')
|
const Constants = preload('res://addons/Wol/core/constants.gd')
|
||||||
const StandardLibrary = preload('res://addons/Wol/core/libraries/standard.gd')
|
|
||||||
const VirtualMachine = preload('res://addons/Wol/core/virtual_machine.gd')
|
const VirtualMachine = preload('res://addons/Wol/core/virtual_machine.gd')
|
||||||
const WolLibrary = preload('res://addons/Wol/core/library.gd')
|
|
||||||
const Value = preload('res://addons/Wol/core/value.gd')
|
const Value = preload('res://addons/Wol/core/value.gd')
|
||||||
|
|
||||||
var _variableStorage
|
var _variableStorage
|
||||||
|
@ -14,42 +10,21 @@ var _program
|
||||||
var library
|
var library
|
||||||
|
|
||||||
var _vm
|
var _vm
|
||||||
|
|
||||||
var _visitedNodeCount = {}
|
var _visitedNodeCount = {}
|
||||||
|
|
||||||
var executionComplete
|
|
||||||
|
|
||||||
func _init(variableStorage):
|
func _init(variableStorage):
|
||||||
_variableStorage = variableStorage
|
_variableStorage = variableStorage
|
||||||
_vm = VirtualMachine.new(self)
|
|
||||||
library = WolLibrary.new()
|
|
||||||
executionComplete = false
|
|
||||||
|
|
||||||
# import the standard library
|
|
||||||
# this contains math constants, operations and checks
|
|
||||||
library.import_library(StandardLibrary.new())#FIX
|
|
||||||
|
|
||||||
#add a function to lib that checks if node is visited
|
|
||||||
library.register_function('visited', -1, funcref(self, 'is_node_visited'), true)
|
|
||||||
|
|
||||||
#add function to lib that gets the node visit count
|
|
||||||
library.register_function('visit_count', -1, funcref(self, 'node_visit_count'), true)
|
|
||||||
|
|
||||||
func is_active():
|
func is_active():
|
||||||
return get_exec_state() != Constants.ExecutionState.Stopped
|
return get_exec_state() != Constants.ExecutionState.Stopped
|
||||||
|
|
||||||
#gets the current execution state of the virtual machine
|
|
||||||
func get_exec_state():
|
|
||||||
return _vm.executionState
|
|
||||||
|
|
||||||
func set_selected_option(option):
|
func set_selected_option(option):
|
||||||
_vm.set_selected_option(option)
|
_vm.set_selected_option(option)
|
||||||
|
|
||||||
func set_node(name = DEFAULT_START):
|
func set_node(name = 'Start'):
|
||||||
_vm.set_node(name)
|
_vm.set_node(name)
|
||||||
|
|
||||||
func start():
|
func start():
|
||||||
print('got here')
|
|
||||||
if _vm.executionState == Constants.ExecutionState.Stopped:
|
if _vm.executionState == Constants.ExecutionState.Stopped:
|
||||||
_vm.resume()
|
_vm.resume()
|
||||||
|
|
||||||
|
@ -65,29 +40,7 @@ func pause():
|
||||||
func stop():
|
func stop():
|
||||||
_vm.stop()
|
_vm.stop()
|
||||||
|
|
||||||
func get_all_nodes():
|
func node_exists(name):
|
||||||
return _program.nodes.keys()
|
|
||||||
|
|
||||||
func current_node():
|
|
||||||
return _vm.get_current()
|
|
||||||
|
|
||||||
func get_node_id(name):
|
|
||||||
if _program.nodes.size() == 0:
|
|
||||||
return ''
|
|
||||||
if _program.nodes.has(name):
|
|
||||||
return 'id:'+name
|
|
||||||
else:
|
|
||||||
return ''
|
|
||||||
|
|
||||||
func unloadAll(clear_visited:bool = true):
|
|
||||||
if clear_visited :
|
|
||||||
_visitedNodeCount.clear()
|
|
||||||
_program = null
|
|
||||||
|
|
||||||
func dump()->String:
|
|
||||||
return _program.dump(library)
|
|
||||||
|
|
||||||
func node_exists(name:String)->bool:
|
|
||||||
return _program.nodes.has(name)
|
return _program.nodes.has(name)
|
||||||
|
|
||||||
func set_program(program):
|
func set_program(program):
|
||||||
|
@ -95,32 +48,7 @@ func set_program(program):
|
||||||
_vm.set_program(_program)
|
_vm.set_program(_program)
|
||||||
_vm.reset()
|
_vm.reset()
|
||||||
|
|
||||||
func get_program():
|
|
||||||
return _program
|
|
||||||
|
|
||||||
func get_vm():
|
func get_vm():
|
||||||
return _vm
|
return _vm
|
||||||
|
|
||||||
func is_node_visited(node = _vm.current_node_name()):
|
|
||||||
return node_visit_count(node) > 0
|
|
||||||
|
|
||||||
func node_visit_count(node = _vm.current_node_name()):
|
|
||||||
if node is Value:
|
|
||||||
node = _program.strings[node.value()].text
|
|
||||||
|
|
||||||
var visitCount : int = 0
|
|
||||||
if _visitedNodeCount.has(node):
|
|
||||||
visitCount = _visitedNodeCount[node]
|
|
||||||
|
|
||||||
|
|
||||||
print('visit count for %s is %d' % [node, visitCount])
|
|
||||||
|
|
||||||
return visitCount
|
|
||||||
|
|
||||||
func get_visited_nodes():
|
|
||||||
return _visitedNodeCount.keys()
|
|
||||||
|
|
||||||
func set_visited_nodes(visitedList):
|
|
||||||
_visitedNodeCount.clear()
|
|
||||||
for string in visitedList:
|
|
||||||
_visitedNodeCount[string] = 1
|
|
||||||
|
|
|
@ -1,69 +0,0 @@
|
||||||
extends 'res://addons/Wol/core/library.gd'
|
|
||||||
|
|
||||||
const Value = preload('res://addons/Wol/core/value.gd')
|
|
||||||
|
|
||||||
func _init():
|
|
||||||
register_function('Add', 2, funcref(self, 'add'), true)
|
|
||||||
register_function('Minus', 2, funcref(self, 'sub'), true)
|
|
||||||
register_function('UnaryMinus', 1, funcref(self, 'unary_minus'), true)
|
|
||||||
register_function('Divide', 2, funcref(self, 'div'), true)
|
|
||||||
register_function('Multiply', 2, funcref(self, 'mul'), true)
|
|
||||||
register_function('Modulo', 2, funcref(self, 'mod'), true)
|
|
||||||
register_function('EqualTo', 2, funcref(self, 'equal'), true)
|
|
||||||
register_function('NotEqualTo', 2, funcref(self, 'noteq'), true)
|
|
||||||
register_function('GreaterThan', 2, funcref(self, 'ge'), true)
|
|
||||||
register_function('GreaterThanOrEqualTo', 2, funcref(self, 'geq'), true)
|
|
||||||
register_function('LessThan', 2, funcref(self, 'le'), true)
|
|
||||||
register_function('LessThanOrEqualTo', 2, funcref(self, 'leq'), true)
|
|
||||||
register_function('And', 2, funcref(self, 'land'), true)
|
|
||||||
register_function('Or', 2, funcref(self, 'lor'), true)
|
|
||||||
register_function('Xor', 2, funcref(self, 'xor'), true)
|
|
||||||
register_function('Not', 1, funcref(self, 'lnot'), true)
|
|
||||||
|
|
||||||
func add(param1, param2):
|
|
||||||
return param1.add(param2)
|
|
||||||
|
|
||||||
func sub(param1, param2):
|
|
||||||
return param1.sub(param2)
|
|
||||||
|
|
||||||
func unary_minus(param1):
|
|
||||||
return param1.negative()
|
|
||||||
|
|
||||||
func div(param1, param2):
|
|
||||||
return param1.div(param2)
|
|
||||||
|
|
||||||
func mul(param1, param2):
|
|
||||||
return param1.mult(param2)
|
|
||||||
|
|
||||||
func mod(param1, param2):
|
|
||||||
return param1.mod(param2)
|
|
||||||
|
|
||||||
func equal(param1, param2):
|
|
||||||
return param1.equals(param2)
|
|
||||||
|
|
||||||
func noteq(param1, param2):
|
|
||||||
return !param1.equals(param2)
|
|
||||||
|
|
||||||
func ge(param1, param2):
|
|
||||||
return param1.greater(param2)
|
|
||||||
|
|
||||||
func geq(param1, param2):
|
|
||||||
return param1.geq(param2)
|
|
||||||
|
|
||||||
func le(param1, param2):
|
|
||||||
return param1.less(param2)
|
|
||||||
|
|
||||||
func leq(param1, param2):
|
|
||||||
return param1.leq(param2)
|
|
||||||
|
|
||||||
func land(param1, param2):
|
|
||||||
return param1.as_bool() and param2.as_bool()
|
|
||||||
|
|
||||||
func lor(param1, param2):
|
|
||||||
return param1.as_bool() or param2.as_bool()
|
|
||||||
|
|
||||||
func xor(param1, param2):
|
|
||||||
return param1.as_bool() != param2.as_bool()
|
|
||||||
|
|
||||||
func lnot(param1):
|
|
||||||
return not param1.as_bool()
|
|
|
@ -1,28 +1,24 @@
|
||||||
extends Object
|
extends Object
|
||||||
|
|
||||||
const FunctionInfo = preload("res://addons/Wol/core/function_info.gd")
|
const FunctionInfo = preload('res://addons/Wol/core/function_info.gd')
|
||||||
const Constants = preload('res://addons/Wol/core/constants.gd')
|
const Constants = preload('res://addons/Wol/core/constants.gd')
|
||||||
|
|
||||||
var functions : Dictionary = {}# String , FunctionInfo
|
var functions = {}
|
||||||
|
var virtual_machine
|
||||||
|
|
||||||
func get_function(name:String)->FunctionInfo:
|
func get_function(name):
|
||||||
if functions.has(name):
|
if functions.has(name):
|
||||||
return functions[name]
|
return functions[name]
|
||||||
else :
|
else :
|
||||||
printerr("Invalid Function: %s"% name)
|
printerr('Invalid Function: %s'% name)
|
||||||
return null
|
return
|
||||||
|
|
||||||
func import_library(other)->void:
|
func import_library(other):
|
||||||
Constants.merge_dir(functions, other.functions)
|
Constants.merge_dir(functions, other.functions)
|
||||||
|
|
||||||
func register_function(name: String, paramCount: int, function: FuncRef, returnsValue: bool):
|
func register_function(name, parameter_count, function, returns_value):
|
||||||
var functionInfo: FunctionInfo = FunctionInfo.new(name, paramCount, function, returnsValue)
|
var functionInfo = FunctionInfo.new(name, parameter_count, function, returns_value)
|
||||||
functions[name] = functionInfo
|
functions[name] = functionInfo
|
||||||
|
|
||||||
func deregister_function(name: String):
|
func deregister_function(name):
|
||||||
if !functions.erase(name):
|
functions.erase(name)
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -8,48 +8,62 @@ const EXECUTION_COMPLETE : String = 'execution_complete_command'
|
||||||
var NULL_VALUE = Value.new(null)
|
var NULL_VALUE = Value.new(null)
|
||||||
|
|
||||||
# Function references to handlers
|
# Function references to handlers
|
||||||
var lineHandler
|
var line_handler
|
||||||
var optionsHandler
|
var options_handler
|
||||||
var commandHandler
|
var command_handler
|
||||||
var nodeStartHandler
|
var node_start_handler
|
||||||
var nodeCompleteHandler
|
var node_finished_handler
|
||||||
var dialogueCompleteHandler
|
var dialogue_finished_handler
|
||||||
|
|
||||||
var _dialogue
|
var dialogue
|
||||||
var _program
|
var libraries
|
||||||
|
var program
|
||||||
var _state
|
var _state
|
||||||
|
|
||||||
var _currentNode
|
var _currentNode
|
||||||
|
|
||||||
var executionState = Constants.ExecutionState.Stopped
|
var execution_state = Constants.ExecutionState.Stopped
|
||||||
|
|
||||||
var string_table = {}
|
var string_table = {}
|
||||||
|
|
||||||
func _init(dialogue):
|
func _init(_dialogue, _libraries):
|
||||||
self._dialogue = dialogue
|
dialogue = _dialogue
|
||||||
_state = VmState.new()
|
libraries = _libraries
|
||||||
|
libraries.virtual_machine = self
|
||||||
|
|
||||||
func set_program(program):
|
line_handler = funcref(dialogue, '_on_line')
|
||||||
_program = program
|
options_handler = funcref(dialogue, '_on_options')
|
||||||
|
command_handler = funcref(dialogue, '_on_command')
|
||||||
|
node_start_handler = funcref(dialogue, '_on_node_start')
|
||||||
|
node_finished_handler = funcref(dialogue, '_on_node_finished')
|
||||||
|
dialogue_finished_handler = funcref(dialogue, '_on_dialogue_finished')
|
||||||
|
|
||||||
|
assert(line_handler.is_valid(), 'Cannot run without a line handler (_on_line)')
|
||||||
|
assert(options_handler.is_valid(), 'Cannot run without a options handler (_on_options)')
|
||||||
|
assert(command_handler.is_valid(), 'Cannot run without a command handler (_on_command)')
|
||||||
|
assert(node_start_handler.is_valid(), 'Cannot run without a node start handler (_on_node_start)')
|
||||||
|
assert(node_finished_handler.is_valid(), 'Cannot run without a node finished handler (_on_node_finished)')
|
||||||
|
|
||||||
|
_state = VmState.new()
|
||||||
|
|
||||||
#set the node to run
|
#set the node to run
|
||||||
#return true if successeful false if no node
|
#return true if successeful false if no node
|
||||||
#of that name found
|
#of that name found
|
||||||
func set_node(name:String) -> bool:
|
func set_node(name):
|
||||||
if _program == null || _program.nodes.size() == 0:
|
if program == null || program.nodes.size() == 0:
|
||||||
printerr('Could not load %s : no nodes loaded' % name)
|
printerr('Could not load %s : no nodes loaded' % name)
|
||||||
return false
|
return false
|
||||||
|
|
||||||
if !_program.nodes.has(name):
|
if !program.nodes.has(name):
|
||||||
executionState = Constants.ExecutionState.Stopped
|
execution_state = Constants.ExecutionState.Stopped
|
||||||
reset()
|
reset()
|
||||||
printerr('No node named %s has been loaded' % name)
|
printerr('No node named %s has been loaded' % name)
|
||||||
return false
|
return false
|
||||||
|
|
||||||
_currentNode = _program.nodes[name]
|
_currentNode = program.nodes[name]
|
||||||
reset()
|
reset()
|
||||||
_state.currentNodeName = name
|
_state.currentNodeName = name
|
||||||
nodeStartHandler.call_func(name)
|
node_start_handler.call_func(name)
|
||||||
return true
|
return true
|
||||||
|
|
||||||
func current_node_name()->String:
|
func current_node_name()->String:
|
||||||
|
@ -59,11 +73,11 @@ func current_node():
|
||||||
return _currentNode
|
return _currentNode
|
||||||
|
|
||||||
func pause():
|
func pause():
|
||||||
executionState = Constants.ExecutionState.Suspended
|
execution_state = Constants.ExecutionState.Suspended
|
||||||
|
|
||||||
#stop exectuion
|
#stop exectuion
|
||||||
func stop():
|
func stop():
|
||||||
executionState = Constants.ExecutionState.Stopped
|
execution_state = Constants.ExecutionState.Stopped
|
||||||
reset()
|
reset()
|
||||||
_currentNode = null
|
_currentNode = null
|
||||||
|
|
||||||
|
@ -71,7 +85,7 @@ func stop():
|
||||||
#resume execution if waiting for result
|
#resume execution if waiting for result
|
||||||
#return false if error
|
#return false if error
|
||||||
func set_selected_option(id):
|
func set_selected_option(id):
|
||||||
if executionState != Constants.ExecutionState.WaitingForOption:
|
if execution_state != Constants.ExecutionState.WaitingForOption:
|
||||||
printerr('Unable to select option when dialogue not waiting for option')
|
printerr('Unable to select option when dialogue not waiting for option')
|
||||||
return false
|
return false
|
||||||
|
|
||||||
|
@ -84,7 +98,7 @@ func set_selected_option(id):
|
||||||
_state.currentOptions.clear()
|
_state.currentOptions.clear()
|
||||||
|
|
||||||
#no longer waiting for option
|
#no longer waiting for option
|
||||||
executionState = Constants.ExecutionState.Suspended
|
execution_state = Constants.ExecutionState.Suspended
|
||||||
|
|
||||||
return true
|
return true
|
||||||
|
|
||||||
|
@ -99,42 +113,26 @@ func resume():
|
||||||
printerr('Cannot run dialogue with no node selected')
|
printerr('Cannot run dialogue with no node selected')
|
||||||
return false
|
return false
|
||||||
|
|
||||||
if executionState == Constants.ExecutionState.WaitingForOption:
|
if execution_state == Constants.ExecutionState.WaitingForOption:
|
||||||
printerr('Cannot run while waiting for option')
|
printerr('Cannot run while waiting for option')
|
||||||
return false
|
return false
|
||||||
|
|
||||||
if lineHandler == null:
|
|
||||||
printerr('Cannot run without a lineHandler')
|
|
||||||
return false
|
|
||||||
|
|
||||||
if optionsHandler == null:
|
|
||||||
printerr('Cannot run without an optionsHandler')
|
|
||||||
return false
|
|
||||||
|
|
||||||
if commandHandler == null:
|
execution_state = Constants.ExecutionState.Running
|
||||||
printerr('Cannot run without an commandHandler')
|
|
||||||
return false
|
|
||||||
if nodeStartHandler == null:
|
|
||||||
printerr('Cannot run without a nodeStartHandler')
|
|
||||||
return false
|
|
||||||
if nodeCompleteHandler == null:
|
|
||||||
printerr('Cannot run without an nodeCompleteHandler')
|
|
||||||
return false
|
|
||||||
|
|
||||||
executionState = Constants.ExecutionState.Running
|
|
||||||
|
|
||||||
#execute instruction until something cool happens
|
#execute instruction until something cool happens
|
||||||
while executionState == Constants.ExecutionState.Running:
|
while execution_state == Constants.ExecutionState.Running:
|
||||||
var currentInstruction = _currentNode.instructions[_state.programCounter]
|
var currentInstruction = _currentNode.instructions[_state.programCounter]
|
||||||
|
|
||||||
run_instruction(currentInstruction)
|
run_instruction(currentInstruction)
|
||||||
_state.programCounter += 1
|
_state.programCounter += 1
|
||||||
|
|
||||||
if _state.programCounter >= _currentNode.instructions.size():
|
if _state.programCounter >= _currentNode.instructions.size():
|
||||||
nodeCompleteHandler.call_func(_currentNode.nodeName)
|
node_finished_handler.call_func(_currentNode.nodeName)
|
||||||
executionState = Constants.ExecutionState.Stopped
|
execution_state = Constants.ExecutionState.Stopped
|
||||||
reset()
|
reset()
|
||||||
dialogueCompleteHandler.call_func()
|
dialogue_finished_handler.call_func()
|
||||||
|
|
||||||
return true
|
return true
|
||||||
|
|
||||||
|
@ -158,17 +156,17 @@ func run_instruction(instruction)->bool:
|
||||||
#pass it to client as line
|
#pass it to client as line
|
||||||
var key = instruction.operands[0].value
|
var key = instruction.operands[0].value
|
||||||
|
|
||||||
var line = _program.strings[key]
|
var line = program.strings[key]
|
||||||
|
|
||||||
#the second operand is the expression count
|
#the second operand is the expression count
|
||||||
# of format function
|
# of format function
|
||||||
if instruction.operands.size() > 1:
|
if instruction.operands.size() > 1:
|
||||||
pass#add format function support
|
pass#add format function support
|
||||||
|
|
||||||
var pause : int = lineHandler.call_func(line)
|
var pause = line_handler.call_func(line)
|
||||||
|
|
||||||
if pause == Constants.HandlerState.PauseExecution:
|
if pause == Constants.HandlerState.PauseExecution:
|
||||||
executionState = Constants.ExecutionState.Suspended
|
execution_state = Constants.ExecutionState.Suspended
|
||||||
|
|
||||||
Constants.ByteCode.RunCommand:
|
Constants.ByteCode.RunCommand:
|
||||||
var commandText : String = instruction.operands[0].value
|
var commandText : String = instruction.operands[0].value
|
||||||
|
@ -178,9 +176,9 @@ func run_instruction(instruction)->bool:
|
||||||
|
|
||||||
var command = Program.Command.new(commandText)
|
var command = Program.Command.new(commandText)
|
||||||
|
|
||||||
var pause = commandHandler.call_func(command) as int
|
var pause = command_handler.call_func(command) as int
|
||||||
if pause == Constants.HandlerState.PauseExecution:
|
if pause == Constants.HandlerState.PauseExecution:
|
||||||
executionState = Constants.ExecutionState.Suspended
|
execution_state = Constants.ExecutionState.Suspended
|
||||||
|
|
||||||
Constants.ByteCode.PushString:
|
Constants.ByteCode.PushString:
|
||||||
#push String var to stack
|
#push String var to stack
|
||||||
|
@ -217,7 +215,7 @@ func run_instruction(instruction)->bool:
|
||||||
#push any return value to stack
|
#push any return value to stack
|
||||||
var functionName : String = instruction.operands[0].value
|
var functionName : String = instruction.operands[0].value
|
||||||
|
|
||||||
var function = _dialogue.library.get_function(functionName)
|
var function = libraries.get_function(functionName)
|
||||||
|
|
||||||
var expected_parameter_count : int = function.paramCount
|
var expected_parameter_count : int = function.paramCount
|
||||||
var actual_parameter_count : int = _state.pop_value().as_number()
|
var actual_parameter_count : int = _state.pop_value().as_number()
|
||||||
|
@ -250,20 +248,21 @@ func run_instruction(instruction)->bool:
|
||||||
Constants.ByteCode.PushVariable:
|
Constants.ByteCode.PushVariable:
|
||||||
#get content of variable and push to stack
|
#get content of variable and push to stack
|
||||||
var name : String = instruction.operands[0].value
|
var name : String = instruction.operands[0].value
|
||||||
var loaded = _dialogue._variableStorage.get_value(name)
|
# TODO: Reimplement variable storage
|
||||||
|
var loaded = dialogue.variable_storage.get_value(name)
|
||||||
_state.push_value(loaded)
|
_state.push_value(loaded)
|
||||||
|
|
||||||
Constants.ByteCode.StoreVariable:
|
Constants.ByteCode.StoreVariable:
|
||||||
#store top stack value to variable
|
#store top stack value to variable
|
||||||
var top = _state.peek_value()
|
var top = _state.peek_value()
|
||||||
var destination : String = instruction.operands[0].value
|
var destination : String = instruction.operands[0].value
|
||||||
_dialogue._variableStorage.set_value(destination,top)
|
dialogue.variable_storage.set_value(destination,top)
|
||||||
|
|
||||||
Constants.ByteCode.Stop:
|
Constants.ByteCode.Stop:
|
||||||
#stop execution and repost it
|
#stop execution and repost it
|
||||||
nodeCompleteHandler.call_func(_currentNode.name)
|
node_finished_handler.call_func(_currentNode.name)
|
||||||
dialogueCompleteHandler.call_func()
|
dialogue_finished_handler.call_func()
|
||||||
executionState = Constants.ExecutionState.Stopped
|
execution_state = Constants.ExecutionState.Stopped
|
||||||
reset()
|
reset()
|
||||||
|
|
||||||
Constants.ByteCode.RunNode:
|
Constants.ByteCode.RunNode:
|
||||||
|
@ -276,17 +275,17 @@ func run_instruction(instruction)->bool:
|
||||||
else :
|
else :
|
||||||
name = instruction.operands[0].value
|
name = instruction.operands[0].value
|
||||||
|
|
||||||
var pause = nodeCompleteHandler.call_func(_currentNode.name)
|
var pause = node_finished_handler.call_func(_currentNode.name)
|
||||||
set_node(name)
|
set_node(name)
|
||||||
_state.programCounter-=1
|
_state.programCounter-=1
|
||||||
if pause == Constants.HandlerState.PauseExecution:
|
if pause == Constants.HandlerState.PauseExecution:
|
||||||
executionState = Constants.ExecutionState.Suspended
|
execution_state = Constants.ExecutionState.Suspended
|
||||||
|
|
||||||
Constants.ByteCode.AddOption:
|
Constants.ByteCode.AddOption:
|
||||||
# add an option to current state
|
# add an option to current state
|
||||||
var key = instruction.operands[0].value
|
var key = instruction.operands[0].value
|
||||||
|
|
||||||
var line = _program.strings[key]
|
var line = program.strings[key]
|
||||||
|
|
||||||
if instruction.operands.size() > 2:
|
if instruction.operands.size() > 2:
|
||||||
pass #formated text options
|
pass #formated text options
|
||||||
|
@ -297,9 +296,9 @@ func run_instruction(instruction)->bool:
|
||||||
Constants.ByteCode.ShowOptions:
|
Constants.ByteCode.ShowOptions:
|
||||||
#show options - stop if none
|
#show options - stop if none
|
||||||
if _state.currentOptions.size() == 0:
|
if _state.currentOptions.size() == 0:
|
||||||
executionState = Constants.ExecutionState.Stopped
|
execution_state = Constants.ExecutionState.Stopped
|
||||||
reset()
|
reset()
|
||||||
dialogueCompleteHandler.call_func()
|
dialogue_finished_handler.call_func()
|
||||||
return false
|
return false
|
||||||
|
|
||||||
#present list of options
|
#present list of options
|
||||||
|
@ -309,16 +308,15 @@ func run_instruction(instruction)->bool:
|
||||||
choices.append(Program.Option.new(option.key, optionIndex, option.value))
|
choices.append(Program.Option.new(option.key, optionIndex, option.value))
|
||||||
|
|
||||||
#we cant continue until option chosen
|
#we cant continue until option chosen
|
||||||
executionState = Constants.ExecutionState.WaitingForOption
|
execution_state = Constants.ExecutionState.WaitingForOption
|
||||||
|
|
||||||
#pass the options to the client
|
#pass the options to the client
|
||||||
#delegate for them to call
|
#delegate for them to call
|
||||||
#when user makes selection
|
#when user makes selection
|
||||||
|
|
||||||
optionsHandler.call_func(choices)
|
options_handler.call_func(choices)
|
||||||
_:
|
_:
|
||||||
#bytecode messed up woopsise
|
execution_state = Constants.ExecutionState.Stopped
|
||||||
executionState = Constants.ExecutionState.Stopped
|
|
||||||
reset()
|
reset()
|
||||||
printerr('Unknown Bytecode %s' % instruction.operation)
|
printerr('Unknown Bytecode %s' % instruction.operation)
|
||||||
return false
|
return false
|
||||||
|
|
Reference in a new issue