init
This commit is contained in:
commit
b99855351d
434 changed files with 50357 additions and 0 deletions
146
addons/inkgd/editor/common/executors/ink_compiler.gd
Normal file
146
addons/inkgd/editor/common/executors/ink_compiler.gd
Normal file
|
@ -0,0 +1,146 @@
|
|||
# ############################################################################ #
|
||||
# Copyright © 2019-2022 Frédéric Maquin <fred@ephread.com>
|
||||
# Licensed under the MIT License.
|
||||
# See LICENSE in the project root for license information.
|
||||
# ############################################################################ #
|
||||
|
||||
extends InkExternalCommandExecutor
|
||||
|
||||
class_name InkCompiler
|
||||
|
||||
# ############################################################################ #
|
||||
# Imports
|
||||
# ############################################################################ #
|
||||
|
||||
var InkExecutionResult = load("res://addons/inkgd/editor/common/executors/structures/ink_execution_result.gd")
|
||||
|
||||
# ############################################################################ #
|
||||
# Private Properties
|
||||
# ############################################################################ #
|
||||
|
||||
## Ink Configuration
|
||||
var _configuration: InkCompilationConfiguration
|
||||
|
||||
# ############################################################################ #
|
||||
# Signals
|
||||
# ############################################################################ #
|
||||
|
||||
## Emitted when a compilation completed. Note that this doesn't imply that
|
||||
## the compulation was successful. Check the content of result
|
||||
## (InkCompiler.Result) for more information.
|
||||
signal story_compiled(result)
|
||||
|
||||
# ############################################################################ #
|
||||
# Overrides
|
||||
# ############################################################################ #
|
||||
|
||||
func _init(configuration: InkCompilationConfiguration):
|
||||
_configuration = configuration
|
||||
|
||||
if _configuration.use_threads:
|
||||
_thread = Thread.new()
|
||||
|
||||
# ############################################################################ #
|
||||
# Methods
|
||||
# ############################################################################ #
|
||||
|
||||
## Compile the story, based on the compilation configuration provided
|
||||
## by this object. If `configuration.use_thread` is set to `false`,
|
||||
## this method will return `true` if the compilation succeeded and `false`
|
||||
## otherwise. If `configuration.use_thread` is set to `true`, this method
|
||||
## always returns `true`.
|
||||
func compile_story() -> bool:
|
||||
if _configuration.use_threads:
|
||||
var error = _thread.start(Callable(self, "_compile_story").bind(_configuration), Thread.PRIORITY_HIGH)
|
||||
|
||||
if error != OK:
|
||||
var result = InkExecutionResult.new(
|
||||
self.identifier,
|
||||
_configuration.use_threads,
|
||||
_configuration.user_triggered,
|
||||
false,
|
||||
""
|
||||
)
|
||||
|
||||
call_deferred("emit_signal", "story_compiled", result)
|
||||
|
||||
return true
|
||||
else:
|
||||
return _compile_story(_configuration)
|
||||
|
||||
# ############################################################################ #
|
||||
# Private Helpers
|
||||
# ############################################################################ #
|
||||
|
||||
## Compile the story, based on the given compilation configuration
|
||||
## If `configuration.use_thread` is set to `false`, this method will
|
||||
## return `true` if the compilation succeeded and `false` otherwise.
|
||||
## If `configuration.use_thread` is set to `false`, this method always
|
||||
## returns `true`.
|
||||
func _compile_story(config: InkCompilationConfiguration) -> bool:
|
||||
print("[inkgd] [INFO] Executing compilation command…")
|
||||
var return_code = 0
|
||||
var output = []
|
||||
|
||||
var start_time = Time.get_ticks_msec()
|
||||
|
||||
if config.use_mono:
|
||||
var args = [config.inklecate_path, '-o', config.target_file_path, config.source_file_path]
|
||||
return_code = OS.execute(config.mono_path, args, output, true, false)
|
||||
else:
|
||||
var args = ['-o', config.target_file_path, config.source_file_path]
|
||||
return_code = OS.execute(config.inklecate_path, args, output, true, false)
|
||||
|
||||
var end_time = Time.get_ticks_msec()
|
||||
|
||||
print("[inkgd] [INFO] Command executed in %dms." % (end_time - start_time))
|
||||
|
||||
var string_output = PackedStringArray(output)
|
||||
if _configuration.use_threads:
|
||||
call_deferred("_handle_compilation_result", config, return_code, string_output)
|
||||
return true
|
||||
else:
|
||||
var result = _process_compilation_result(config, return_code, string_output)
|
||||
return result.success
|
||||
|
||||
|
||||
## Handles the compilation results when exectuted in a different thread.
|
||||
##
|
||||
## This method should always be executed on the main thread.
|
||||
func _handle_compilation_result(
|
||||
config: InkCompilationConfiguration,
|
||||
return_code: int,
|
||||
output: Array
|
||||
):
|
||||
_thread.wait_to_finish()
|
||||
|
||||
var result = _process_compilation_result(config, return_code, output)
|
||||
emit_signal("story_compiled", result)
|
||||
|
||||
|
||||
## Process the compilation results turning them into an instance of `Result`.
|
||||
##
|
||||
## This method will also print to the editor's output panel.
|
||||
func _process_compilation_result(
|
||||
config: InkCompilationConfiguration,
|
||||
return_code: int,
|
||||
output: PackedStringArray
|
||||
) -> InkExecutionResult:
|
||||
var success: bool = (return_code == 0)
|
||||
var output_text: String = "\n".join(output).replace(BOM, "").strip_edges()
|
||||
|
||||
if success:
|
||||
print("[inkgd] [INFO] %s was successfully compiled." % config.source_file_path)
|
||||
if output_text.length() > 0:
|
||||
print(output_text)
|
||||
else:
|
||||
printerr("[inkgd] [ERROR] Could not compile %s." % config.source_file_path)
|
||||
printerr(output_text)
|
||||
|
||||
return InkExecutionResult.new(
|
||||
self.identifier,
|
||||
config.use_threads,
|
||||
config.user_triggered,
|
||||
success,
|
||||
output_text
|
||||
)
|
152
addons/inkgd/editor/common/executors/ink_configuration_tester.gd
Normal file
152
addons/inkgd/editor/common/executors/ink_configuration_tester.gd
Normal file
|
@ -0,0 +1,152 @@
|
|||
# ############################################################################ #
|
||||
# Copyright © 2019-2022 Frédéric Maquin <fred@ephread.com>
|
||||
# Licensed under the MIT License.
|
||||
# See LICENSE in the project root for license information.
|
||||
# ############################################################################ #
|
||||
|
||||
extends InkExternalCommandExecutor
|
||||
|
||||
class_name InkConfigurationTester
|
||||
|
||||
# ############################################################################ #
|
||||
# Imports
|
||||
# ############################################################################ #
|
||||
|
||||
var InkExecutionResult = load("res://addons/inkgd/editor/common/executors/structures/ink_execution_result.gd")
|
||||
|
||||
# ############################################################################ #
|
||||
# Private Properties
|
||||
# ############################################################################ #
|
||||
|
||||
## Ink Configuration
|
||||
var _configuration: InkExecutionConfiguration
|
||||
|
||||
# ############################################################################ #
|
||||
# Signals
|
||||
# ############################################################################ #
|
||||
|
||||
## Emitted when a test completed. Note that this doesn't imply that
|
||||
## the test was successful. Check the content of result
|
||||
## (InkConfigurationTester.Result) for more information.
|
||||
signal availability_tested(result)
|
||||
|
||||
# ############################################################################ #
|
||||
# Overrides
|
||||
# ############################################################################ #
|
||||
|
||||
func _init(configuration: InkExecutionConfiguration):
|
||||
_configuration = configuration
|
||||
|
||||
if _configuration.use_threads:
|
||||
_thread = Thread.new()
|
||||
|
||||
# ############################################################################ #
|
||||
# Methods
|
||||
# ############################################################################ #
|
||||
|
||||
## Test inklecate's availability, based on the configuration provided by this object.
|
||||
## If `configuration.use_thread` is set to `false`, this method will return
|
||||
## an instance of `InkExecutionResult`, otherwise, it will return `null`.
|
||||
func test_availability():
|
||||
if _configuration.use_threads:
|
||||
var error = _thread.start(Callable(self, "_test_availablity").bind(_configuration), Thread.PRIORITY_HIGH)
|
||||
if error != OK:
|
||||
var result = InkExecutionResult.new(
|
||||
self.identifier,
|
||||
_configuration.use_threads,
|
||||
_configuration.user_triggered,
|
||||
false,
|
||||
""
|
||||
)
|
||||
|
||||
emit_signal("availability_tested", result)
|
||||
return true
|
||||
else:
|
||||
return _test_availability(_configuration)
|
||||
|
||||
# ############################################################################ #
|
||||
# Private Helpers
|
||||
# ############################################################################ #
|
||||
|
||||
## Test inklecate's availability, based on the configuration provided by this object
|
||||
## If `configuration.use_thread` is set to `false`, this method will return
|
||||
## an instance of `InkExecutionResult`, otherwise, it will return `null`.
|
||||
func _test_availability(config: InkExecutionConfiguration):
|
||||
print("[inkgd] [INFO] Executing test command…")
|
||||
var return_code = 0
|
||||
var output = []
|
||||
|
||||
var start_time = Time.get_ticks_msec()
|
||||
|
||||
if config.use_mono:
|
||||
var args = [config.inklecate_path]
|
||||
return_code = OS.execute(config.mono_path, args, output, true, false)
|
||||
|
||||
else:
|
||||
return_code = OS.execute(config.inklecate_path, [], output, true, false)
|
||||
|
||||
var end_time = Time.get_ticks_msec()
|
||||
|
||||
print("[inkgd] [INFO] Command executed in %dms." % (end_time - start_time))
|
||||
|
||||
var string_output = PackedStringArray(output)
|
||||
if _configuration.use_threads:
|
||||
call_deferred("_handle_test_result", config, return_code, string_output)
|
||||
return null
|
||||
else:
|
||||
return _process_test_result(config, return_code, string_output)
|
||||
|
||||
|
||||
## Handles the test result when exectuted in a different thread.
|
||||
##
|
||||
## This method should always be executed on the main thread.
|
||||
func _handle_test_result(config: InkExecutionConfiguration, return_code: int, output: Array):
|
||||
_thread.wait_to_finish()
|
||||
|
||||
var result = _process_test_result(config, return_code, output)
|
||||
emit_signal("availability_tested", result)
|
||||
|
||||
|
||||
## Process the compilation results turning them into an instance of `Result`.
|
||||
##
|
||||
## This method will also print to the editor's output panel.
|
||||
func _process_test_result(
|
||||
config: InkExecutionConfiguration,
|
||||
return_code: int,
|
||||
output: PackedStringArray
|
||||
) -> InkExecutionResult:
|
||||
var success: bool = (return_code == 0 || _contains_inklecate_output_prefix(output))
|
||||
var output_text: String = "\n".join(output).replace(BOM, "").strip_edges()
|
||||
|
||||
if success:
|
||||
if !output_text.is_empty():
|
||||
print("[inkgd] [INFO] inklecate was found and executed:")
|
||||
print(output_text)
|
||||
else:
|
||||
print("[inkgd] [INFO] inklecate was found and executed.")
|
||||
else:
|
||||
printerr("[inkgd] [ERROR] Something went wrong while testing inklecate's setup.")
|
||||
printerr(output_text)
|
||||
|
||||
return InkExecutionResult.new(
|
||||
self.identifier,
|
||||
config.use_threads,
|
||||
config.user_triggered,
|
||||
success,
|
||||
output_text
|
||||
)
|
||||
|
||||
|
||||
## Guess whether the provided `output_array` looks like the usage inklecate
|
||||
## outputs when run with no parameters.
|
||||
func _contains_inklecate_output_prefix(output_array: PackedStringArray):
|
||||
# No valid output -> it's not inklecate.
|
||||
if output_array.size() == 0: return false
|
||||
|
||||
# The first line of the output is cleaned up by removing the BOM and
|
||||
# any sort of whitespace/unprintable character.
|
||||
var cleaned_line = output_array[0].replace(BOM, "").strip_edges()
|
||||
|
||||
# If the first line starts with the correct substring, it's likely
|
||||
# to be inklecate!
|
||||
return cleaned_line.find("Usage: inklecate2") == 0
|
|
@ -0,0 +1,32 @@
|
|||
# ############################################################################ #
|
||||
# Copyright © 2019-2022 Frédéric Maquin <fred@ephread.com>
|
||||
# Licensed under the MIT License.
|
||||
# See LICENSE in the project root for license information.
|
||||
# ############################################################################ #
|
||||
|
||||
extends RefCounted
|
||||
|
||||
class_name InkExternalCommandExecutor
|
||||
|
||||
# ############################################################################ #
|
||||
# Properties
|
||||
# ############################################################################ #
|
||||
|
||||
## The identifier of this compiler.
|
||||
var identifier: int: get = get_identifier
|
||||
func get_identifier() -> int:
|
||||
return get_instance_id()
|
||||
|
||||
# ############################################################################ #
|
||||
# Constants
|
||||
# ############################################################################ #
|
||||
|
||||
const BOM = "\ufeff"
|
||||
|
||||
# ############################################################################ #
|
||||
# Private Properties
|
||||
# ############################################################################ #
|
||||
|
||||
## Thread used to compile the story.
|
||||
@warning_ignore("unused_private_class_variable") # Used by subclasses.
|
||||
var _thread: Thread
|
|
@ -0,0 +1,44 @@
|
|||
# ############################################################################ #
|
||||
# Copyright © 2019-2022 Frédéric Maquin <fred@ephread.com>
|
||||
# Licensed under the MIT License.
|
||||
# See LICENSE in the project root for license information.
|
||||
# ############################################################################ #
|
||||
|
||||
extends InkExecutionConfiguration
|
||||
|
||||
## Contains all the configuration settings necessary to perform a compilation.
|
||||
class_name InkCompilationConfiguration
|
||||
|
||||
# ############################################################################ #
|
||||
# Properties
|
||||
# ############################################################################ #
|
||||
|
||||
## The path to the story to compile, local to the file system.
|
||||
var source_file_path: String = ""
|
||||
|
||||
## The path to the compiled story, local to the file system.
|
||||
var target_file_path: String = ""
|
||||
|
||||
# ############################################################################ #
|
||||
# Overrides
|
||||
# ############################################################################ #
|
||||
|
||||
@warning_ignore("shadowed_variable")
|
||||
func _init(
|
||||
configuration: InkConfiguration,
|
||||
use_threads: bool,
|
||||
user_triggered: bool,
|
||||
source_file_path: String,
|
||||
target_file_path: String
|
||||
):
|
||||
super(configuration, use_threads, user_triggered)
|
||||
self.source_file_path = ProjectSettings.globalize_path(source_file_path)
|
||||
self.target_file_path = ProjectSettings.globalize_path(target_file_path)
|
||||
|
||||
# ############################################################################ #
|
||||
# Private Methods
|
||||
# ############################################################################ #
|
||||
|
||||
func _is_running_on_windows():
|
||||
var os_name = OS.get_name()
|
||||
return (os_name == "Windows" || os_name == "UWP")
|
|
@ -0,0 +1,49 @@
|
|||
@tool
|
||||
# ############################################################################ #
|
||||
# Copyright © 2019-2022 Frédéric Maquin <fred@ephread.com>
|
||||
# Licensed under the MIT License.
|
||||
# See LICENSE in the project root for license information.
|
||||
# ############################################################################ #
|
||||
|
||||
extends RefCounted
|
||||
|
||||
## Contains all the configuration settings necessary to perform an execution.
|
||||
class_name InkExecutionConfiguration
|
||||
|
||||
# ############################################################################ #
|
||||
# Properties
|
||||
# ############################################################################ #
|
||||
|
||||
var use_threads: bool = false
|
||||
var user_triggered: bool = false
|
||||
|
||||
|
||||
var use_mono: bool = false
|
||||
var mono_path: String = ""
|
||||
var inklecate_path: String = ""
|
||||
|
||||
# ############################################################################ #
|
||||
# Overrides
|
||||
# ############################################################################ #
|
||||
|
||||
@warning_ignore("shadowed_variable")
|
||||
func _init(
|
||||
configuration: InkConfiguration,
|
||||
use_threads: bool,
|
||||
user_triggered: bool
|
||||
):
|
||||
self.use_threads = use_threads
|
||||
self.user_triggered = user_triggered
|
||||
|
||||
self.use_mono = !_is_running_on_windows() && configuration.use_mono
|
||||
|
||||
self.mono_path = configuration.mono_path
|
||||
self.inklecate_path = configuration.inklecate_path
|
||||
|
||||
# ############################################################################ #
|
||||
# Private Methods
|
||||
# ############################################################################ #
|
||||
|
||||
func _is_running_on_windows():
|
||||
var os_name = OS.get_name()
|
||||
return (os_name == "Windows" || os_name == "UWP")
|
|
@ -0,0 +1,44 @@
|
|||
# ############################################################################ #
|
||||
# Copyright © 2019-2022 Frédéric Maquin <fred@ephread.com>
|
||||
# Licensed under the MIT License.
|
||||
# See LICENSE in the project root for license information.
|
||||
# ############################################################################ #
|
||||
|
||||
extends RefCounted
|
||||
|
||||
## A test result, containing information about whether the test
|
||||
## suceeded and the generated output.
|
||||
class_name InkExecutionResult
|
||||
|
||||
# ############################################################################ #
|
||||
# Properties
|
||||
# ############################################################################ #
|
||||
|
||||
## The identifier of the compiler that generated this result.
|
||||
## This is the value of 'InkExecutor.identifier'.
|
||||
var identifier: int = 0
|
||||
|
||||
var use_threads: bool = false
|
||||
var user_triggered: bool = false
|
||||
|
||||
var success: bool = false
|
||||
|
||||
var output: String = ""
|
||||
|
||||
# ############################################################################ #
|
||||
# Overrides
|
||||
# ############################################################################ #
|
||||
|
||||
@warning_ignore("shadowed_variable")
|
||||
func _init(
|
||||
identifier: int,
|
||||
use_threads: bool,
|
||||
user_triggered: bool,
|
||||
success: bool,
|
||||
output: String
|
||||
):
|
||||
self.identifier = identifier
|
||||
self.use_threads = use_threads
|
||||
self.user_triggered = user_triggered
|
||||
self.success = success
|
||||
self.output = output
|
Loading…
Add table
Add a link
Reference in a new issue