64 lines
1.8 KiB
GDScript
64 lines
1.8 KiB
GDScript
# editor/pokeapi_client.gd
|
|
@tool
|
|
class_name PokeApiClient
|
|
extends Node
|
|
|
|
signal progress(done : int, total : int)
|
|
|
|
const API := "https://pokeapi.co/api/v2/"
|
|
|
|
var _in_flight : int = 0
|
|
var _done : int = 0
|
|
var _total : int = 0
|
|
|
|
func get_bytes(url : String) -> PackedByteArray:
|
|
for attempt in 3:
|
|
var http := HTTPRequest.new()
|
|
add_child(http)
|
|
if http.request(url) != OK:
|
|
http.queue_free()
|
|
await get_tree().create_timer(1.0).timeout
|
|
continue
|
|
var res : Array = await http.request_completed
|
|
http.queue_free()
|
|
if res[0] == HTTPRequest.RESULT_SUCCESS and res[1] == 200:
|
|
return res[3]
|
|
if res[1] == 404: break
|
|
await get_tree().create_timer(1.0).timeout
|
|
return PackedByteArray()
|
|
|
|
func get_json(url : String) -> Variant:
|
|
var bytes := await get_bytes(url)
|
|
if bytes.is_empty(): return null
|
|
return JSON.parse_string(bytes.get_string_from_utf8())
|
|
|
|
## Télécharge une URL vers un fichier. Retourne le chemin, ou "" en cas d'échec.
|
|
func download_file(url : Variant, path : String) -> String:
|
|
if url == null: return ""
|
|
var bytes := await get_bytes(String(url))
|
|
if bytes.is_empty(): return ""
|
|
var f := FileAccess.open(path, FileAccess.WRITE)
|
|
if f == null: return ""
|
|
f.store_buffer(bytes)
|
|
f.close()
|
|
return path
|
|
|
|
## Lance worker(item) pour chaque élément, avec un nombre limité de tâches simultanées.
|
|
func run_parallel(items : Array, worker : Callable) -> void:
|
|
_done = 0
|
|
_total = items.size()
|
|
progress.emit(0, _total)
|
|
for item in items:
|
|
while _in_flight >= PokeApiSettings.max_concurrent():
|
|
await get_tree().process_frame
|
|
_in_flight += 1
|
|
_run_task(worker, item)
|
|
while _in_flight > 0:
|
|
await get_tree().process_frame
|
|
|
|
func _run_task(worker : Callable, item : Variant) -> void:
|
|
await worker.call(item)
|
|
_in_flight -= 1
|
|
_done += 1
|
|
progress.emit(_done, _total)
|