extends BuildingPart class_name Producer @export var produced_item: Item @export var output_period: float = 0.1 @export var max_outputs: int = 1 @export var consumers: Array[Consumer] var last_consumer_idx: int = 0 #var output_timer: float = 0.0 #var output_item: Item class ItemRequest: var item: Item var timeout: float var requests: Array[ItemRequest] = [] signal requested_item_received(request: ItemRequest) func _process(delta: float) -> void: for request in requests: request.timeout -= delta if request.timeout <= 0: cancel_request(request) func can_produce() -> bool: return can_send_item(produced_item) func produce() -> bool: return send_item(produced_item) func can_send_item(item: Item) -> bool: if !enabled: return false for request in requests: if request.item == item: return true for consumer in consumers: if consumer.can_accept_item(item): return true return false func send_item(item: Item) -> bool: if !enabled: return false if check_requested_items(item): return true if consumers.is_empty(): return false var start_idx: int = last_consumer_idx var first_try: bool = true var idx: int = start_idx while idx != start_idx or first_try: idx += 1 if idx >= consumers.size(): idx = 0 first_try = false var consumer: Consumer = consumers[idx] var accepted: bool = consumer.offer_item(item) if accepted: last_consumer_idx = idx return true return false func check_requested_items(new_item: Item) -> bool: for request in requests: if new_item == request.item: requested_item_received.emit(request) return true return false func cancel_request(request: ItemRequest): requested_item_received.emit(request) ## Waits for an item to be available at this storage, or a timeout to be reached. func wait_for_item(item: Item, timeout: float) -> bool: var request: ItemRequest = ItemRequest.new() request.item = item request.timeout = timeout requests.append(request) var finished_request: ItemRequest = null while finished_request != request: finished_request = await requested_item_received requests.erase(request) return finished_request.timeout > 0