Skip to content

Improve runtime resources (timelines and characters created through code) #2537

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion addons/dialogic/Core/DialogicGameHandler.gd
Original file line number Diff line number Diff line change
Expand Up @@ -439,6 +439,6 @@ func print_debug_moment() -> void:
if not current_timeline:
return

printerr("\tAt event ", current_event_idx+1, " (",current_timeline_events[current_event_idx].event_name, ' Event) in timeline "', DialogicResourceUtil.get_unique_identifier(current_timeline.resource_path), '" (',current_timeline.resource_path,').')
printerr("\tAt event ", current_event_idx+1, " (",current_timeline_events[current_event_idx].event_name, ' Event) in timeline "', current_timeline.get_identifier(), '" (',current_timeline.resource_path,').')
print("\n")
#endregion
26 changes: 22 additions & 4 deletions addons/dialogic/Core/DialogicResourceUtil.gd
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ static func add_resource_to_directory(file_path:String, directory:Dictionary) ->

## Returns the unique identifier for the given resource path.
## Returns an empty string if no identifier was found.
static func get_unique_identifier(file_path:String) -> String:
static func get_unique_identifier_by_path(file_path:String) -> String:
if not file_path: return ""
var identifier: Variant = get_directory(file_path.get_extension()).find_key(file_path)
if typeof(identifier) == TYPE_STRING:
Expand All @@ -74,12 +74,15 @@ static func get_unique_identifier(file_path:String) -> String:
## Returns the resource associated with the given unique identifier.
## The expected extension is needed to use the right directory.
static func get_resource_from_identifier(identifier:String, extension:String) -> Resource:
var path: String = get_directory(extension).get(identifier, '')
if ResourceLoader.exists(path):
return load(path)
var value: Variant = get_directory(extension).get(identifier, '')
if typeof(value) == TYPE_STRING and ResourceLoader.exists(value):
return load(value)
elif value is Resource:
return value
return null


## Editor Only
static func change_unique_identifier(file_path:String, new_identifier:String) -> void:
var directory := get_directory(file_path.get_extension())
var key: String = directory.find_key(file_path)
Expand Down Expand Up @@ -113,6 +116,21 @@ static func remove_resource(file_path:String) -> void:
static func is_identifier_unused(extension:String, identifier:String) -> bool:
return not identifier in get_directory(extension)


## While usually the directory maps identifiers to paths, this method (only supposed to be used at runtime)
## allows mapping resources that are not saved to an identifier.
static func register_runtime_resource(resource:Resource, identifier:String, extension:String) -> void:
var directory := get_directory(extension)
directory[identifier] = resource
set_directory(extension, directory)


static func get_runtime_unique_identifier(resource:Resource, extension:String) -> String:
var identifier: Variant = get_directory(extension).find_key(resource)
if typeof(identifier) == TYPE_STRING:
return identifier
return ""

#endregion

#region LABEL CACHE
Expand Down
1 change: 1 addition & 0 deletions addons/dialogic/Core/DialogicUtil.gd
Original file line number Diff line number Diff line change
Expand Up @@ -528,6 +528,7 @@ static func setup_script_property_edit_node(property_info: Dictionary, value:Var
TYPE_DICTIONARY:
input = load("res://addons/dialogic/Editor/Events/Fields/field_dictionary.tscn").instantiate()
input.property_name = property_info["name"]
input.set_value(value)
input.value_changed.connect(_on_export_dict_submitted.bind(property_changed))
TYPE_OBJECT:
input = load("res://addons/dialogic/Editor/Common/hint_tooltip_icon.tscn").instantiate()
Expand Down
6 changes: 3 additions & 3 deletions addons/dialogic/Editor/CharacterEditor/character_editor.gd
Original file line number Diff line number Diff line change
Expand Up @@ -71,9 +71,9 @@ func _open_resource(resource:Resource) -> void:
load_portrait_tree()

loading = false
character_loaded.emit(resource.resource_path)
character_loaded.emit(current_resource.resource_path)

%CharacterName.text = DialogicResourceUtil.get_unique_identifier(resource.resource_path)
%CharacterName.text = current_resource.get_identifier()

$NoCharacterScreen.hide()
%PortraitChangeInfo.hide()
Expand Down Expand Up @@ -549,7 +549,7 @@ func report_name_change(item: TreeItem) -> void:
editors_manager.reference_manager.add_portrait_ref_change(
item.get_meta('previous_name'),
%PortraitTree.get_full_item_name(item),
[DialogicResourceUtil.get_unique_identifier(current_resource.resource_path)])
[current_resource.get_identifier()])
item.set_meta('previous_name', %PortraitTree.get_full_item_name(item))
%PortraitChangeInfo.show()

Expand Down
2 changes: 1 addition & 1 deletion addons/dialogic/Editor/Common/sidebar.gd
Original file line number Diff line number Diff line change
Expand Up @@ -433,7 +433,7 @@ func _on_right_click_menu_id_pressed(id: int) -> void:
)
4: # COPY IDENTIFIER
DisplayServer.clipboard_set(
DialogicResourceUtil.get_unique_identifier(
DialogicResourceUtil.get_unique_identifier_by_path(
%RightClickMenu.get_meta("item_clicked").get_metadata(0)
)
)
Expand Down
4 changes: 2 additions & 2 deletions addons/dialogic/Editor/Events/Fields/field_options_dynamic.gd
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ func _set_value(value:Variant) -> void:
Modes.PRETTY_PATH:
%Search.text = DialogicUtil.pretty_name(value)
Modes.IDENTIFIER when value.begins_with("res://"):
%Search.text = DialogicResourceUtil.get_unique_identifier(value)
%Search.text = DialogicResourceUtil.get_unique_identifier_by_path(value)
Modes.ANY_VALID_STRING when validation_func:
%Search.text = validation_func.call(value).get('valid_text', value)
_:
Expand Down Expand Up @@ -361,7 +361,7 @@ func _can_drop_data(position:Vector2, data:Variant) -> bool:
func _drop_data(position:Vector2, data:Variant) -> void:
var path := str(data.files[0])
if mode == Modes.IDENTIFIER:
path = DialogicResourceUtil.get_unique_identifier(path)
path = DialogicResourceUtil.get_unique_identifier_by_path(path)
_set_value(path)
value_changed.emit(property_name, path)
current_value_updated = false
Expand Down
9 changes: 7 additions & 2 deletions addons/dialogic/Editor/Events/Fields/field_options_fixed.gd
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,11 @@ extends DialogicVisualEditorField

## Event block field for constant options. For varying options use ComplexPicker.

var options: Array = []
var options: Array = []:
set(o):
options = o
if current_value != -1:
set_value(current_value)

## if true, only the symbol will be displayed. In the dropdown text will be visible.
## Useful for making UI simpler
Expand All @@ -21,6 +25,7 @@ func _ready() -> void:
call("get_popup").index_pressed.connect(index_pressed)



func _load_display_info(info:Dictionary) -> void:
options = info.get('options', [])
self.disabled = info.get('disabled', false)
Expand All @@ -35,7 +40,7 @@ func _set_value(value:Variant) -> void:
if !symbol_only:
self.text = option['label']
self.icon = option.get('icon', null)
current_value = value
current_value = value


func get_value() -> Variant:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ func _update_property() -> void:
updating = true
current_value = new_value
if current_value:
field.set_value(DialogicResourceUtil.get_unique_identifier(current_value.resource_path))
field.set_value(current_value.get_identifier())
button.show()
else:
button.hide()
Expand Down
2 changes: 1 addition & 1 deletion addons/dialogic/Editor/TimelineEditor/timeline_editor.gd
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ func _open_resource(resource:Resource) -> void:
EditorMode.TEXT:
%TextEditor.load_timeline(current_resource)
$NoTimelineScreen.hide()
%TimelineName.text = DialogicResourceUtil.get_unique_identifier(current_resource.resource_path)
%TimelineName.text = current_resource.get_identifier()
play_timeline_button.disabled = false


Expand Down
4 changes: 2 additions & 2 deletions addons/dialogic/Modules/Character/event_character.gd
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ var character_identifier: String:
if character_identifier == '--All--':
return '--All--'
if character:
var identifier := DialogicResourceUtil.get_unique_identifier(character.resource_path)
var identifier := character.get_identifier()
if not identifier.is_empty():
return identifier
return character_identifier
Expand Down Expand Up @@ -225,7 +225,7 @@ func to_text() -> String:
if action == Actions.LEAVE and character_identifier == '--All--':
result_string += "--All--"
elif character:
var name := DialogicResourceUtil.get_unique_identifier(character.resource_path)
var name := character.get_character_name()

if name.count(" ") > 0:
name = '"' + name + '"'
Expand Down
10 changes: 5 additions & 5 deletions addons/dialogic/Modules/Character/subsystem_portraits.gd
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ func load_game_state(_load_flag:=LoadFlags.FULL_LOAD) -> void:
var character_info: Dictionary = portraits_info[character_path]
var character: DialogicCharacter = load(character_path)
var container := dialogic.PortraitContainers.load_position_container(character.get_character_name())

ResourceLoader.load_threaded_request(character_path)

var load_status = ResourceLoader.load_threaded_get_status(character_path)
Expand Down Expand Up @@ -138,7 +138,7 @@ func _change_portrait(character_node: Node2D, portrait: String, fade_animation:=

if ResourceLoader.exists(scene_path):
ResourceLoader.load_threaded_request(scene_path)

var load_status = ResourceLoader.load_threaded_get_status(scene_path)
while load_status == ResourceLoader.THREAD_LOAD_IN_PROGRESS:
await get_tree().process_frame
Expand Down Expand Up @@ -371,7 +371,7 @@ func get_valid_portrait(character:DialogicCharacter, portrait:String) -> String:

if not portrait in character.portraits:
if not portrait.is_empty():
printerr('[Dialogic] Tried to use invalid portrait "', portrait, '" on character "', DialogicResourceUtil.get_unique_identifier(character.resource_path), '". Using default portrait instead.')
printerr('[Dialogic] Tried to use invalid portrait "', portrait, '" on character "', character.get_character_name(), '". Using default portrait instead.')
dialogic.print_debug_moment()
portrait = character.default_portrait

Expand Down Expand Up @@ -452,9 +452,9 @@ func add_character(character: DialogicCharacter, container: DialogicNode_Portrai
if not character:
printerr('[DialogicError] Cannot call add_portrait() with null character.')
return null

ResourceLoader.load_threaded_request(character.resource_path)

var load_status = ResourceLoader.load_threaded_get_status(character.resource_path)
while load_status == ResourceLoader.THREAD_LOAD_IN_PROGRESS:
await get_tree().process_frame
Expand Down
2 changes: 1 addition & 1 deletion addons/dialogic/Modules/Jump/event_jump.gd
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ var label_name := ""
var timeline_identifier := "":
get:
if timeline:
var identifier := DialogicResourceUtil.get_unique_identifier(timeline.resource_path)
var identifier := timeline.get_identifier()
if not identifier.is_empty():
return identifier
return timeline_identifier
Expand Down
2 changes: 1 addition & 1 deletion addons/dialogic/Modules/Jump/event_label.gd
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ func _execute() -> void:
"identifier": name,
"display_name": get_property_translated("display_name"),
"display_name_orig": display_name,
"timeline": DialogicResourceUtil.get_unique_identifier(dialogic.current_timeline.resource_path)
"timeline": dialogic.current_timeline.get_identifier()
})
finish()

Expand Down
39 changes: 25 additions & 14 deletions addons/dialogic/Modules/Text/event_text.gd
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ var portrait := ""
var character_identifier: String:
get:
if character:
var identifier := DialogicResourceUtil.get_unique_identifier(character.resource_path)
var identifier := character.get_identifier()
if not identifier.is_empty():
return identifier
return character_identifier
Expand Down Expand Up @@ -274,8 +274,10 @@ func to_text() -> String:
if result.is_empty():
result = "<Empty Text Event>"

if character:
var name := DialogicResourceUtil.get_unique_identifier(character.resource_path)
if character or character_identifier:
var name := character_identifier
if character:
name = character.get_identifier()
if name.count(" ") > 0:
name = '"' + name + '"'
if not portrait.is_empty():
Expand All @@ -296,6 +298,10 @@ func from_text(string:String) -> void:
character = DialogicResourceUtil.get_character_resource(character_identifier)

var result := regex.search(string.trim_prefix('\\'))

if result.get_string('portrait'):
portrait = result.get_string('portrait').strip_edges().trim_prefix('(').trim_suffix(')')

if result and not result.get_string('name').is_empty():
var name := result.get_string('name').strip_edges()

Expand All @@ -307,16 +313,16 @@ func from_text(string:String) -> void:
if character == null and Engine.is_editor_hint() == false:
character = DialogicCharacter.new()
character.display_name = name
character.resource_path = "user://"+name+".dch"
DialogicResourceUtil.add_resource_to_directory(character.resource_path, DialogicResourceUtil.get_character_directory())
character.set_identifier(name)
if portrait:
character.color = Color(portrait)

if !result.get_string('portrait').is_empty():
portrait = result.get_string('portrait').strip_edges().trim_prefix('(').trim_suffix(')')
if not result:
return

if result:
text = result.get_string('text').replace("\\\n", "\n").replace('\\:', ':').strip_edges().trim_prefix('\\')
if text == '<Empty Text Event>':
text = ""
text = result.get_string('text').replace("\\\n", "\n").replace('\\:', ':').strip_edges().trim_prefix('\\')
if text == '<Empty Text Event>':
text = ""


func is_valid_event(_string:String) -> bool:
Expand Down Expand Up @@ -367,7 +373,7 @@ func build_event_editor() -> void:
{'file_extension' : '.dch',
'mode' : 2,
'suggestions_func' : get_character_suggestions,
'empty_text' : '(No one)',
'placeholder' : '(No one)',
'icon' : load("res://addons/dialogic/Editor/Images/Resources/character.svg")}, 'do_any_characters_exist()')
add_header_edit('portrait', ValueType.DYNAMIC_OPTIONS,
{'suggestions_func' : get_portrait_suggestions,
Expand All @@ -387,8 +393,13 @@ func do_any_characters_exist() -> bool:


func get_character_suggestions(search_text:String) -> Dictionary:
return DialogicUtil.get_character_suggestions(search_text, character, true, false, editor_node)

var suggestions := DialogicUtil.get_character_suggestions(search_text, character, true, false, editor_node)
if search_text and not search_text in suggestions:
suggestions[search_text] = {
"value":search_text,
"tooltip": "A temporary character, created on the spot.",
"editor_icon":["GuiEllipsis", "EditorIcons"]}
return suggestions

func get_portrait_suggestions(search_text:String) -> Dictionary:
return DialogicUtil.get_portrait_suggestions(search_text, character, true, "Don't change")
Expand Down
4 changes: 2 additions & 2 deletions addons/dialogic/Modules/Text/subsystem_text.gd
Original file line number Diff line number Diff line change
Expand Up @@ -507,8 +507,8 @@ func collect_character_names() -> void:

character_colors = {}

for dch_path in DialogicResourceUtil.get_character_directory().values():
var character := (load(dch_path) as DialogicCharacter)
for dch_identifier in DialogicResourceUtil.get_character_directory():
var character := (DialogicResourceUtil.get_character_resource(dch_identifier) as DialogicCharacter)

if character.display_name:
if "{" in character.display_name and "}" in character.display_name:
Expand Down
25 changes: 21 additions & 4 deletions addons/dialogic/Resources/character.gd
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
@tool
extends Resource
extends "res://addons/dialogic/Resources/dialogic_identifiable_resource.gd"
class_name DialogicCharacter


Expand Down Expand Up @@ -30,8 +30,12 @@ enum TranslatedProperties {
var _translation_id := ""


func _to_string() -> String:
return "[{name}:{id}]".format({"name":get_character_name(), "id":get_instance_id()})
func _get_extension() -> String:
return "dch"


func _get_resource_name() -> String:
return "DialogicCharacter"


## Adds a translation ID to the character.
Expand Down Expand Up @@ -125,7 +129,7 @@ func get_display_name_translated() -> String:

## Returns the best name for this character.
func get_character_name() -> String:
var unique_identifier := DialogicResourceUtil.get_unique_identifier(resource_path)
var unique_identifier := get_identifier()
if not unique_identifier.is_empty():
return unique_identifier
if not resource_path.is_empty():
Expand All @@ -135,6 +139,19 @@ func get_character_name() -> String:
else:
return "UnnamedCharacter"

#
### Sets the unique identifier-string of this resource.
### In editor (if the resource is already saved) the identifier will be stored.
### In game (if the resource is not stored) the resource will be temporarily registered.
#func set_identifier(new_identifier:String) -> bool:
#if resource_path and Engine.is_editor_hint():
#DialogicResourceUtil.change_unique_identifier(resource_path, new_identifier)
#return true
#if not resource_path and not Engine.is_editor_hint():
#DialogicResourceUtil.register_runtime_resource(self, new_identifier, "dch")
#return true
#return false


## Returns the info of the given portrait.
## Uses the default portrait if the given portrait doesn't exist.
Expand Down
Loading