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
|
204
addons/inkgd/editor/common/ink_configuration.gd
Normal file
204
addons/inkgd/editor/common/ink_configuration.gd
Normal file
|
@ -0,0 +1,204 @@
|
|||
# ############################################################################ #
|
||||
# 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 InkConfiguration
|
||||
|
||||
# ############################################################################ #
|
||||
# Enums
|
||||
# ############################################################################ #
|
||||
|
||||
enum BuildMode {
|
||||
MANUAL = 0,
|
||||
DURING_BUILD,
|
||||
AFTER_CHANGE
|
||||
}
|
||||
|
||||
# ############################################################################ #
|
||||
# Constants
|
||||
# ############################################################################ #
|
||||
|
||||
const ROOT_DIR = "res://"
|
||||
|
||||
const COMPILER_CONFIG = ROOT_DIR + ".inkgd_compiler.cfg"
|
||||
const INK_CONFIG = ROOT_DIR + ".inkgd_ink.cfg"
|
||||
|
||||
const COMPILER_CONFIG_FORMAT_VERSION = 2
|
||||
const INK_CONFIG_FORMAT_VERSION = 2
|
||||
|
||||
const FORMAT_SECTION = "format"
|
||||
const VERSION = "version"
|
||||
|
||||
const INKGD_SECTION = "inkgd"
|
||||
const USE_MONO = "use_mono"
|
||||
const MONO_PATH = "mono_path"
|
||||
const INKLECATE_PATH = "inklecate_path"
|
||||
const COMPILATION_MODE = "compilation_mode"
|
||||
const STORIES = "stories"
|
||||
const SOURCE_FILE_PATH = "source_file_path"
|
||||
const TARGET_FILE_PATH = "target_file_path"
|
||||
const WATCHED_FOLDER_PATH = "watched_folder_path"
|
||||
|
||||
const DEFAULT_STORIES = [
|
||||
{
|
||||
SOURCE_FILE_PATH: "",
|
||||
TARGET_FILE_PATH: "",
|
||||
WATCHED_FOLDER_PATH: ""
|
||||
}
|
||||
]
|
||||
|
||||
# ############################################################################ #
|
||||
# Signals
|
||||
# ############################################################################ #
|
||||
|
||||
signal story_configuration_changed()
|
||||
signal compilation_mode_changed(compilation_mode)
|
||||
|
||||
# ############################################################################ #
|
||||
# Properties
|
||||
# ############################################################################ #
|
||||
|
||||
var use_mono: bool = false
|
||||
var mono_path: String = ""
|
||||
var inklecate_path: String = ""
|
||||
|
||||
var compilation_mode: int = BuildMode.MANUAL: set = set_compilation_mode
|
||||
func set_compilation_mode(new_value: int):
|
||||
compilation_mode = new_value
|
||||
emit_signal("compilation_mode_changed", compilation_mode)
|
||||
|
||||
var stories: Array = DEFAULT_STORIES
|
||||
|
||||
# ############################################################################ #
|
||||
# Private Properties
|
||||
# ############################################################################ #
|
||||
|
||||
var _compiler_config_file = ConfigFile.new()
|
||||
var _ink_config_file = ConfigFile.new()
|
||||
|
||||
# ############################################################################ #
|
||||
# Overrides
|
||||
# ############################################################################ #
|
||||
|
||||
func _init():
|
||||
pass
|
||||
|
||||
# ############################################################################ #
|
||||
# Public Methods
|
||||
# ############################################################################ #
|
||||
|
||||
## Loads the content of the configuration files from disk.
|
||||
func retrieve():
|
||||
_retrieve_inklecate()
|
||||
_retrieve_ink()
|
||||
|
||||
## Stores the content of the configuration to the disk.
|
||||
func persist():
|
||||
_persist_inklecate()
|
||||
_persist_ink()
|
||||
|
||||
func append_new_story_configuration(
|
||||
source_file_path: String,
|
||||
target_file_path: String,
|
||||
wacthed_folder_path: String
|
||||
):
|
||||
stories.append({
|
||||
SOURCE_FILE_PATH: source_file_path,
|
||||
TARGET_FILE_PATH: target_file_path,
|
||||
WATCHED_FOLDER_PATH: wacthed_folder_path
|
||||
})
|
||||
|
||||
emit_signal("story_configuration_changed")
|
||||
|
||||
func remove_story_configuration_at_index(index: int):
|
||||
if index >= 0 && index < stories.size():
|
||||
stories.remove_at(index)
|
||||
|
||||
emit_signal("story_configuration_changed")
|
||||
|
||||
func get_story_configuration_at_index(index):
|
||||
if index >= 0 && index < stories.size():
|
||||
return stories[index]
|
||||
else:
|
||||
return null
|
||||
|
||||
func get_source_file_path(story_configuration):
|
||||
return story_configuration[SOURCE_FILE_PATH]
|
||||
|
||||
func get_target_file_path(story_configuration):
|
||||
return story_configuration[TARGET_FILE_PATH]
|
||||
|
||||
func get_watched_folder_path(story_configuration):
|
||||
return story_configuration[WATCHED_FOLDER_PATH]
|
||||
|
||||
# ############################################################################ #
|
||||
# Private Methods
|
||||
# ############################################################################ #
|
||||
|
||||
## Loads the content of the inklecate configuration file from disk.
|
||||
func _retrieve_inklecate():
|
||||
var err = _compiler_config_file.load(COMPILER_CONFIG)
|
||||
if err != OK:
|
||||
# Assuming it doesn't exist.
|
||||
return
|
||||
|
||||
use_mono = _compiler_config_file.get_value(INKGD_SECTION, USE_MONO, false)
|
||||
mono_path = _compiler_config_file.get_value(INKGD_SECTION, MONO_PATH, "")
|
||||
inklecate_path = _compiler_config_file.get_value(INKGD_SECTION, INKLECATE_PATH, "")
|
||||
|
||||
if _compiler_config_file.get_value(FORMAT_SECTION, VERSION, 0) >= 2:
|
||||
compilation_mode = _compiler_config_file.get_value(INKGD_SECTION, COMPILATION_MODE, 0)
|
||||
|
||||
## Loads the content of the story configuration file from disk.
|
||||
func _retrieve_ink():
|
||||
var err = _ink_config_file.load(INK_CONFIG)
|
||||
if err != OK:
|
||||
# Assuming it doesn't exist.
|
||||
return
|
||||
|
||||
if _ink_config_file.get_value(FORMAT_SECTION, VERSION, 0) >= 2:
|
||||
stories = _ink_config_file.get_value(INKGD_SECTION, STORIES, DEFAULT_STORIES)
|
||||
else:
|
||||
var source_file_path = _ink_config_file.get_value(INKGD_SECTION, SOURCE_FILE_PATH, "")
|
||||
var target_file_path = _ink_config_file.get_value(INKGD_SECTION, TARGET_FILE_PATH, "")
|
||||
var watched_folder_path = _ink_config_file.get_value(INKGD_SECTION, WATCHED_FOLDER_PATH, "")
|
||||
|
||||
stories[0] = {
|
||||
SOURCE_FILE_PATH: source_file_path,
|
||||
TARGET_FILE_PATH: target_file_path,
|
||||
WATCHED_FOLDER_PATH: watched_folder_path
|
||||
}
|
||||
|
||||
## Stores the content of the inklecate configuration to the disk.
|
||||
func _persist_inklecate():
|
||||
_compiler_config_file.set_value(FORMAT_SECTION, VERSION, COMPILER_CONFIG_FORMAT_VERSION)
|
||||
|
||||
_compiler_config_file.set_value(INKGD_SECTION, USE_MONO, use_mono)
|
||||
_compiler_config_file.set_value(INKGD_SECTION, MONO_PATH, mono_path)
|
||||
_compiler_config_file.set_value(INKGD_SECTION, INKLECATE_PATH, inklecate_path)
|
||||
_compiler_config_file.set_value(INKGD_SECTION, COMPILATION_MODE, compilation_mode)
|
||||
|
||||
var err = _compiler_config_file.save(COMPILER_CONFIG)
|
||||
if err != OK:
|
||||
printerr("[inkgd] [ERROR] Could not save: %s" % COMPILER_CONFIG)
|
||||
|
||||
## Stores the content of the story configuration to the disk.
|
||||
func _persist_ink():
|
||||
# Clean up the file if it was created before version 2.
|
||||
if _ink_config_file.has_section_key(INKGD_SECTION, SOURCE_FILE_PATH):
|
||||
_ink_config_file.erase_section_key(INKGD_SECTION, SOURCE_FILE_PATH)
|
||||
|
||||
if _ink_config_file.has_section_key(INKGD_SECTION, TARGET_FILE_PATH):
|
||||
_ink_config_file.erase_section_key(INKGD_SECTION, TARGET_FILE_PATH)
|
||||
|
||||
# Write version 2 values.
|
||||
_ink_config_file.set_value(FORMAT_SECTION, VERSION, COMPILER_CONFIG_FORMAT_VERSION)
|
||||
_ink_config_file.set_value(INKGD_SECTION, STORIES, stories)
|
||||
|
||||
var err = _ink_config_file.save(INK_CONFIG)
|
||||
if err != OK:
|
||||
printerr("[inkgd] [ERROR] Could not save: %s" % INK_CONFIG)
|
103
addons/inkgd/editor/common/ink_csharp_validator.gd
Normal file
103
addons/inkgd/editor/common/ink_csharp_validator.gd
Normal file
|
@ -0,0 +1,103 @@
|
|||
# ############################################################################ #
|
||||
# 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 crude validator catching the most common mistakes.
|
||||
|
||||
class_name InkCSharpValidator
|
||||
|
||||
const INK_ENGINE_RUNTIME = "ink-engine-runtime.dll"
|
||||
|
||||
# ############################################################################ #
|
||||
# Methods
|
||||
# ############################################################################ #
|
||||
|
||||
func validate_csharp_project_files(project_name) -> bool:
|
||||
var ink_engine_runtime := get_runtime_path()
|
||||
|
||||
if ink_engine_runtime.is_empty():
|
||||
print(
|
||||
"[inkgd] [INFO] 'ink-engine-runtime.dll' seems to be missing " +
|
||||
"from the project. If you encounter errors while building the " +
|
||||
"solution, please refer to [TO BE ADDED] for help."
|
||||
)
|
||||
return false
|
||||
|
||||
return _validate_csproj(project_name, ink_engine_runtime)
|
||||
|
||||
func get_runtime_path() -> String:
|
||||
return _scan_directory("res://")
|
||||
|
||||
func _validate_csproj(project_name: String, runtime_path: String) -> bool:
|
||||
var csproj_path = "res://%s.csproj" % project_name
|
||||
|
||||
if !FileAccess.file_exists(csproj_path):
|
||||
printerr(
|
||||
("[inkgd] [ERROR] The C# project (%s.csproj) doesn't exist. " % project_name) +
|
||||
"You can create a new C# project through " +
|
||||
"Project > Tools > C# > Create C# Solution. Alternatively, you can also set " +
|
||||
"Project Settings > General > Inkgd > Do Not Use Mono Runtime to 'Yes' " +
|
||||
"if you do not wish to use the C# version of Ink. "
|
||||
)
|
||||
return false
|
||||
|
||||
var file := FileAccess.open(csproj_path, FileAccess.READ)
|
||||
var error := FileAccess.get_open_error()
|
||||
if error != OK:
|
||||
printerr(
|
||||
"[inkgd] [ERROR] The C# project (%s.csproj) exists but it could not be opened." +
|
||||
"(Code %d)" % [project_name, error]
|
||||
)
|
||||
return false
|
||||
|
||||
var content := file.get_as_text()
|
||||
file.close()
|
||||
|
||||
if content.find(runtime_path.replace("res://", "")) == -1:
|
||||
print(
|
||||
"[inkgd] [INFO] '%s.csproj' seems to be missing a " % project_name +
|
||||
"<RefCounted> item matching '%s'. If you encounter " % runtime_path +
|
||||
"further errors please refer to [TO BE ADDED] for help."
|
||||
)
|
||||
return false
|
||||
|
||||
print("[inkgd] [INFO] The C# Project seems to be configured correctly.")
|
||||
return true
|
||||
|
||||
func _scan_directory(path) -> String:
|
||||
var directory := DirAccess.open(path)
|
||||
var error := DirAccess.get_open_error()
|
||||
if error != OK:
|
||||
printerr(
|
||||
"[inkgd] [ERROR] Could not open '%s', " % path +
|
||||
"can't look for ink-engine-runtime.dll."
|
||||
)
|
||||
return ""
|
||||
|
||||
if directory.list_dir_begin() != OK:# TODOConverter3To4 fill missing arguments https://github.com/godotengine/godot/pull/40547
|
||||
printerr(
|
||||
"[inkgd] [ERROR] Could not list contents of '%s', " % path +
|
||||
"can't look for ink-engine-runtime.dll."
|
||||
)
|
||||
return ""
|
||||
|
||||
var file_name := directory.get_next()
|
||||
while file_name != "":
|
||||
if directory.current_is_dir():
|
||||
var ink_runtime = _scan_directory(
|
||||
"%s/%s" % [directory.get_current_dir(), file_name]
|
||||
)
|
||||
|
||||
if !ink_runtime.is_empty():
|
||||
return ink_runtime
|
||||
else:
|
||||
if file_name == INK_ENGINE_RUNTIME:
|
||||
return "%s/%s" % [directory.get_current_dir(), file_name]
|
||||
|
||||
file_name = directory.get_next()
|
||||
|
||||
return ""
|
84
addons/inkgd/editor/common/ink_editor_interface.gd
Normal file
84
addons/inkgd/editor/common/ink_editor_interface.gd
Normal file
|
@ -0,0 +1,84 @@
|
|||
# ############################################################################ #
|
||||
# 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 InkEditorInterface
|
||||
|
||||
# ############################################################################ #
|
||||
# Signals
|
||||
# ############################################################################ #
|
||||
|
||||
## Emitted when 'Ink' resources (i. e. files with the '.ink' extension) were
|
||||
## reimported by Godot.
|
||||
signal ink_ressources_reimported(resources)
|
||||
|
||||
# ############################################################################ #
|
||||
# Properties
|
||||
# ############################################################################ #
|
||||
|
||||
## The pixel display scale of the editor.
|
||||
var scale: float = 1.0
|
||||
|
||||
var editor_interface: EditorInterface
|
||||
var editor_settings: EditorSettings
|
||||
var editor_filesystem: EditorFileSystem
|
||||
|
||||
## `true` if the editor is running on Windows, `false` otherwise.
|
||||
var is_running_on_windows: bool: get = get_is_running_on_windows
|
||||
func get_is_running_on_windows() -> bool:
|
||||
var os_name = OS.get_name()
|
||||
return (os_name == "Windows" || os_name == "UWP")
|
||||
|
||||
|
||||
# ############################################################################ #
|
||||
# Overrides
|
||||
# ############################################################################ #
|
||||
|
||||
@warning_ignore("shadowed_variable")
|
||||
func _init(editor_interface: EditorInterface):
|
||||
self.editor_interface = editor_interface
|
||||
self.editor_settings = editor_interface.get_editor_settings()
|
||||
self.editor_filesystem = editor_interface.get_resource_filesystem()
|
||||
|
||||
scale = editor_interface.get_editor_scale()
|
||||
|
||||
self.editor_filesystem.connect("resources_reimported", Callable(self, "_resources_reimported"))
|
||||
|
||||
# ############################################################################ #
|
||||
# Methods
|
||||
# ############################################################################ #
|
||||
|
||||
## Tell Godot to scan for updated resources.
|
||||
func scan_file_system():
|
||||
self.editor_filesystem.scan()
|
||||
|
||||
## Tell Godot to scan the given resource.
|
||||
func update_file(path: String):
|
||||
self.editor_filesystem.update_file(path)
|
||||
|
||||
## Returns a custom header color based on the editor's base color.
|
||||
##
|
||||
## If the base color is not found, return 'Color.transparent'.
|
||||
func get_custom_header_color() -> Color:
|
||||
var color = self.editor_settings.get_setting("interface/theme/base_color")
|
||||
if color != null:
|
||||
return Color.from_hsv(color.h * 0.99, color.s * 0.6, color.v * 1.1)
|
||||
else:
|
||||
return Color.TRANSPARENT
|
||||
|
||||
# ############################################################################ #
|
||||
# Signal Receivers
|
||||
# ############################################################################ #
|
||||
|
||||
func _resources_reimported(resources):
|
||||
var ink_resources := PackedStringArray()
|
||||
|
||||
for resource in resources:
|
||||
if resource.get_extension() == "ink":
|
||||
ink_resources.append(resource)
|
||||
|
||||
emit_signal("ink_ressources_reimported", ink_resources)
|
Loading…
Add table
Add a link
Reference in a new issue