Giter Site home page Giter Site logo

immersiverpg / godotasyncloader Goto Github PK

View Code? Open in Web Editor NEW
35.0 2.0 4.0 692 KB

A Godot plugin to load, instance, and add scenes asynchronously using a background thread.

Home Page: https://godotengine.org/asset-library/asset/1376

License: MIT License

GDScript 97.31% Shell 2.69%
godot load async

godotasyncloader's People

Contributors

workhorsy avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

godotasyncloader's Issues

Add error handler callback

Because AsyncLoader.load_scene_async_with_cb is async, there is a chance that the target, instance, and cb have been deleted before use. So we would have to do a bunch of checks for each callback. Rather than do that, have a callback that is called on any of these situations.

func _on_orange_loaded_cb(instance : Node, data : Dictionary) -> void:
	# Just return if target is invalid
	if not is_instance_valid(target):
		return

	# Just return if instance is invalid
	if not is_instance_valid(instance):
		return

	# Just return if the cb is invalid
	if cb != null and not cb.is_valid():
		return
func _on_error(instance : Node, data : Dictionary) -> void:
	# Just return if target is invalid
	if not is_instance_valid(target):
		return

	# Just return if instance is invalid
	if not is_instance_valid(instance):
		return

	# Just return if the cb is invalid
	if cb != null and not cb.is_valid():
		return

AsyncLoader.start(groups, 100, funcref(self,"_on_error" ))

Replace 3 singletons with 1

Instead of having SceneAdder, SceneLoader, and SceneSwitcher, just have AsyncLoader. This should also get rid of the cyclic import error that requires restart.

Then our API can be:

AsyncLoader.set_groups()
AsyncLoader.change_scene_async()
AsyncLoader.load_scene_async()
AsyncLoader.load_scene_async_with_cb()
AsyncLoader.load_scene_sync()

Add a way to remove scenes from cache?

I was looking at SceneLoader.gd, specifically the _get_cached_scene function, and it looks like scenes never get removed from the _scenes cache. It looks like the cache just going to grow and grow while the game runs, using ever more memory. Some way to remove scenes from the cache will probably be needed for larger games.

Move thread setup out of AutoLoad _enter_tree

Having threads start inside AutoLoad can lead to crashes. This is because the main loop (and signal system) isn't loaded yet, and we have to poll for its existence like so:

func _enter_tree() -> void:
	_thread = Thread.new()
	var err = _thread.start(self, "_run_thread", 0, Thread.PRIORITY_LOW)
	assert(err == OK)

func _run_thread(_arg : int) -> void:
	# Wait for main loop to initialize
	var is_waiting_for_main_loop_to_load := true
	while is_waiting_for_main_loop_to_load:
		var loop = self.get_tree()
		if loop != null:
			is_waiting_for_main_loop_to_load = false

		if is_waiting_for_main_loop_to_load:
			print("Still waiting for main loop to initialize ...")
			OS.delay_msec(100)

	# Do actual thread stuff here ...

Also, setting up the plugin like this, is annoying and not obvious to users:

const GROUPS := [
	"terrain",
	"building",
]

func _ready() -> void:
	AsyncLoader._sleep_msec = 100
	AsyncLoader.set_groups(GROUPS)

So we can replace both of these with a start function that does setup and starts threads:

const GROUPS := [
	"terrain",
	"structure",
]
const SLEEP_MSEC := 100

func _ready() -> void:
	AsyncLoader.start(GROUPS, SLEEP_MSEC)

Make logging display times for each chunk

Make output like this:

!!!!!! scene load res://src/World/World.tscn
    $Plants/Cactus
    load 10 ms in THREAD
    instance 13 ms in THREAD
    add 0 ms in MAIN!!!!!!!!!!!!

    $Plants/Cactus2
    load 2 ms in THREAD
    instance 13 ms in THREAD
    add 0 ms in MAIN!!!!!!!!!!!!

Get some lag spikes while loading ?

Hi !
I searched for a plugin like yours because having my scene loading at start makes my game a bit long to load so I wanted to delay some loading while the player is in the menus.
I managed to get the plugin to work even if I'm in 2D, but for some reasons I still get little lag spikes when it loads.

I don't know exactly what could cause this,

Here is basically the code I'm using (I removed all "position" related args everywhere as I don't need them and it was not compatible with 2D)

Init :

const GROUPS := [
	"Foreground",
	"UI",
	"Background",
]
const SLEEP_MSEC := 100

func _init():
	SceneAdder._sleep_msec = 100
	SceneAdder.set_groups(GROUPS)

async calls :

func async_load(path,type,to_assign=null):
	yield(get_tree(),"idle_frame")
	var target
	
	match type:
		"canvas":
			target = canvas_layer
		"background":
			target = background
		"foreground":
			target = foreground
		"middle":
			target = middle
	
	
	if to_assign == null:
		SceneLoader.load_scene_async(target, path)
	else:
		SceneLoader.load_scene_async_with_cb(target, path, funcref(self, "handle_load_callback"), {"type":type,"to_assign":to_assign})

Callback :

func handle_load_callback(path : String, instance : Node, data : Dictionary) -> void:
	propagate_call("add_"+data.type,[instance])
	
	match data.to_assign:
		"fight_scene":
			fight_scene = instance
		"codex":
			codex = instance
AsyncLoadLagSpike.mp4

The game scene is not deleted?

With this extension, I switched from the main menu to the game scene. Later, I switched from the game scene to the main menu. I deleted the game scene with the commands get_tree().get_root().call_deferred("remove_child", game_scene) and game_scene.queue_free(). However, when I return to the main menu scene, the game scene is loading again. What should I do?

Make SceneAdder groups customizable

We shouldn't need to hard code groups to add. Make it so they are setup in code:

const CATEGORIES := [
	"terrain",
	"building",
	"furniture",
	"plant",
	"item",
	"npc",
	"etc",
]

func _init() -> void:
	SceneAdder.set_categories(CATEGORIES)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.