fix off-by-one in bounded range
This commit is contained in:
parent
d0310c693b
commit
143dc9d288
5 changed files with 50 additions and 23 deletions
|
@ -1,13 +1,17 @@
|
||||||
class_name IntRange extends RefCounted
|
class_name IntRange extends RefCounted
|
||||||
|
|
||||||
var min: int
|
var minmax: PackedInt32Array
|
||||||
var max: int
|
|
||||||
|
var min: int:
|
||||||
|
get: return minmax[0]
|
||||||
|
|
||||||
|
var max: int:
|
||||||
|
get: return minmax[1]
|
||||||
|
|
||||||
static var Zero = IntRange.new(0, 0)
|
static var Zero = IntRange.new(0, 0)
|
||||||
|
|
||||||
func _init(start: int, end: int, inclusive: bool = false) -> void:
|
func _init(start: int, end: int, inclusive: bool = false) -> void:
|
||||||
min = start
|
minmax = PackedInt32Array([start, end if not inclusive else end + 1])
|
||||||
max = end if not inclusive else end + 1
|
|
||||||
|
|
||||||
func length() -> int:
|
func length() -> int:
|
||||||
return absi(max - min)
|
return absi(max - min)
|
||||||
|
|
|
@ -23,6 +23,7 @@ func next() -> Option:
|
||||||
return current_value
|
return current_value
|
||||||
elif limit > 0:
|
elif limit > 0:
|
||||||
limit -= 1
|
limit -= 1
|
||||||
index = bounds.wrap(index)
|
var current_value = bounds.wrap(index)
|
||||||
return Option.some(index)
|
index = current_value + 1
|
||||||
|
return Option.some(current_value)
|
||||||
else: return Option.none
|
else: return Option.none
|
||||||
|
|
|
@ -2,7 +2,7 @@ class_name HItemList extends HBoxContainer
|
||||||
|
|
||||||
@export var item_scene: PackedScene
|
@export var item_scene: PackedScene
|
||||||
@export var max_items: int = 4
|
@export var max_items: int = 4
|
||||||
@export var buffered_items: int = 2
|
@export var buffered_items: int = 1
|
||||||
@onready var buffer_size = max_items + (buffered_items * 2)
|
@onready var buffer_size = max_items + (buffered_items * 2)
|
||||||
|
|
||||||
var items: Array = []
|
var items: Array = []
|
||||||
|
@ -11,12 +11,22 @@ var bind_item: Callable = _bind_item
|
||||||
var ring_buffer: RingBuffer
|
var ring_buffer: RingBuffer
|
||||||
|
|
||||||
func _ready() -> void:
|
func _ready() -> void:
|
||||||
ring_buffer = RingBuffer.new(items.size(), buffer_size)
|
ring_buffer = RingBuffer.new(items.size(), buffer_size, 1, -buffered_items)
|
||||||
ring_buffer.updated.connect(_on_updated)
|
ring_buffer.updated.connect(_on_updated)
|
||||||
|
|
||||||
for _i in range(buffer_size):
|
for _i in range(buffer_size):
|
||||||
add_child(create_item.call())
|
add_child(create_item.call())
|
||||||
|
|
||||||
|
_hide_buffered_items()
|
||||||
|
|
||||||
|
func _hide_buffered_items():
|
||||||
|
for i in range(buffered_items):
|
||||||
|
get_child(i).hide()
|
||||||
|
|
||||||
|
var length = buffer_size - 1
|
||||||
|
for i in range(length, length - buffered_items, -1):
|
||||||
|
get_child(i).hide()
|
||||||
|
|
||||||
func _create_item() -> Node:
|
func _create_item() -> Node:
|
||||||
return item_scene.instantiate()
|
return item_scene.instantiate()
|
||||||
|
|
||||||
|
@ -30,10 +40,13 @@ func _on_updated(_current_range: IntRange, _previous_range: IntRange):
|
||||||
func _update_display():
|
func _update_display():
|
||||||
var indices: Array = ring_buffer.range().collect()
|
var indices: Array = ring_buffer.range().collect()
|
||||||
|
|
||||||
|
prints(indices, ring_buffer.start_index, ring_buffer.end_index, ring_buffer.capacity)
|
||||||
for i in range(min(indices.size(), max_items)):
|
for i in range(min(indices.size(), max_items)):
|
||||||
var node = get_child(i + 1)
|
var node = get_child(i)
|
||||||
|
prints(ring_buffer.index(i))
|
||||||
var item = items[indices[i]]
|
var item = items[indices[i]]
|
||||||
bind_item.call(node, item)
|
if item != null:
|
||||||
|
bind_item.call(node, item)
|
||||||
|
|
||||||
func add_item(item: Variant):
|
func add_item(item: Variant):
|
||||||
items.append(item)
|
items.append(item)
|
||||||
|
|
|
@ -4,6 +4,4 @@ class_name InventoryUI extends VBoxContainer
|
||||||
@export var item_list: HItemList
|
@export var item_list: HItemList
|
||||||
|
|
||||||
func _ready() -> void:
|
func _ready() -> void:
|
||||||
print(inventory)
|
|
||||||
print(inventory.items)
|
|
||||||
item_list.add_items(inventory.items)
|
item_list.add_items(inventory.items)
|
||||||
|
|
|
@ -12,7 +12,7 @@ var source_size: int:
|
||||||
get: return _source_size
|
get: return _source_size
|
||||||
set(value): set_source_size(value)
|
set(value): set_source_size(value)
|
||||||
|
|
||||||
func set_source_size(value: int):
|
func set_source_size(value: int) -> void:
|
||||||
assert(value >= 0, "source size must be a non-negative integer")
|
assert(value >= 0, "source size must be a non-negative integer")
|
||||||
_source_size = value
|
_source_size = value
|
||||||
|
|
||||||
|
@ -21,44 +21,55 @@ var capacity: int:
|
||||||
get: return _capacity
|
get: return _capacity
|
||||||
set(value): set_capacity(value)
|
set(value): set_capacity(value)
|
||||||
|
|
||||||
func set_capacity(value: int):
|
func set_capacity(value: int) -> void:
|
||||||
_capacity = value
|
_capacity = value
|
||||||
|
|
||||||
|
var _offset: int
|
||||||
|
var offset: int:
|
||||||
|
get: return _offset
|
||||||
|
set(value): set_offset(value)
|
||||||
|
|
||||||
|
func set_offset(value: int) -> void:
|
||||||
|
_offset = value
|
||||||
|
|
||||||
var _index: int
|
var _index: int
|
||||||
|
|
||||||
var selected_index: int:
|
var selected_index: int:
|
||||||
get: return _index
|
get: return _index
|
||||||
set(value): set_selected(value)
|
set(value): set_selected(value)
|
||||||
|
|
||||||
func set_selected(value: int):
|
func set_selected(value: int) -> void:
|
||||||
_index = self.wrap(value)
|
_index = self.index(value)
|
||||||
|
|
||||||
var start_index: int:
|
var start_index: int:
|
||||||
get: return _index
|
get: return self.index(_offset + _index)
|
||||||
|
|
||||||
var end_index: int:
|
var end_index: int:
|
||||||
get: return self.wrap(_index + _capacity - 1)
|
get: return self.index(_offset + _index + _capacity - 1)
|
||||||
|
|
||||||
@warning_ignore("shadowed_variable")
|
@warning_ignore("shadowed_variable")
|
||||||
func _init(source_size: int, capacity: int, start_index: int = 0) -> void:
|
func _init(source_size: int, capacity: int, start_index: int = 0, offset: int = 0) -> void:
|
||||||
self.source_size = source_size
|
self.source_size = source_size
|
||||||
self.capacity = capacity
|
self.capacity = capacity
|
||||||
selected_index = start_index
|
selected_index = start_index
|
||||||
|
self.offset = offset
|
||||||
|
|
||||||
func wrap(value: int) -> int:
|
func index(value: int) -> int:
|
||||||
if _source_size == 0:
|
if _source_size == 0:
|
||||||
return 0
|
return 0
|
||||||
|
elif value < 0:
|
||||||
|
return _source_size + value % _source_size
|
||||||
else:
|
else:
|
||||||
return value % _source_size
|
return value % _source_size
|
||||||
|
|
||||||
func range() -> RangeIterator:
|
func range() -> BoundedRangeIterator:
|
||||||
return RangeIterator.new(IntRange.new(start_index, end_index))
|
return BoundedRangeIterator.new(IntRange.new(start_index, end_index), IntRange.new(0, capacity))
|
||||||
|
|
||||||
func move(direction: Direction) -> Result:
|
func move(direction: Direction) -> Result:
|
||||||
if _source_size <= _capacity:
|
if _source_size <= _capacity:
|
||||||
return Result.err("source size is smaller than buffer capacity")
|
return Result.err("source size is smaller than buffer capacity")
|
||||||
var previous = range()
|
var previous = range()
|
||||||
_index = self.wrap(_index + direction)
|
_index = self.index(_index + direction)
|
||||||
updated.emit(range(), previous)
|
updated.emit(range(), previous)
|
||||||
return Result.Unit
|
return Result.Unit
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue