QodotPlugin / qodot-plugin

(LEGACY) Quake .map support for Godot 3.x
MIT License
960 stars 70 forks source link

Investigate auto-reload functionality using Godot's resource system #91

Open Shfty opened 4 years ago

Shfty commented 4 years ago

The import plugin already does change detection and reimports when Godot receives focus, but the import plugin itself is essentially a stub placeholder due to overly large maps crashing the editor if implemented that way.

Should be able to hook up some signals to notify QodotMap and trigger a build.

silentorb commented 2 years ago

I looked into this a little and wasn't able to find a way to listen for the source map changing, at least not through GDScript. I tried adding a call to emit_changed( ) from the Qodot map import plugin but that didn't trigger anything when connected to from another script. That's probably in part because the import plugin saves the resource file in the .import folder while in the rest of the app the resource only appears as the source file path: there are two different resources in play and I'm not sure how to bridge the gap from within a scene.

For now, I created a utility script that triggers auto-building the map while I'm editing it.

extends Node
tool

# This script will auto-full-build a Qodot map whenever it's source file
# is modified

# To use, attach this script to a node (the auto-builder node) in the scene with your Qodot map
# and set the auto-builder node's map property to be the Qodot map node

# This script is only intended for live editing sessions and will only
# run when the scene with this script is active in the editor

export (NodePath) var map
export (int) var frequency = 60 * 2 # Defaults to 2 seconds
export (int) var last_modified = 0 # Not meant to be set by the user

onready var _map: QodotMap = get_node(map)
var step = 0

func _ready():
    if not Engine.is_editor_hint():
        queue_free()

func _physics_process(delta):
    if Engine.is_editor_hint() && _map != null:
        step += 1
        if step > 60 * 2:
            step = 0
            var resource_path = _map.map_file
            # Ideally this would be checking the .import file hashes but
            # I haven't found a means through the GDScript API to determine
            # The associated .import files for a resource
            var modified = File.new().get_modified_time(resource_path)

            if last_modified != modified:
                print('Rebuilding modified map...')
                _map.should_add_children = true
                _map.should_set_owners = true
                _map.verify_and_build()
                last_modified = modified