upload the stuff !!
This commit is contained in:
parent
f28029c189
commit
446150e4ac
9 changed files with 315 additions and 67 deletions
139
godot/addons/collections/bst.gd
Normal file
139
godot/addons/collections/bst.gd
Normal file
|
@ -0,0 +1,139 @@
|
|||
class_name BST
|
||||
|
||||
class _Node extends RefCounted:
|
||||
var value: int
|
||||
var left: Option = Option.none
|
||||
var right: Option = Option.none
|
||||
|
||||
func _init(value: int) -> void:
|
||||
self.value = value
|
||||
|
||||
func size() -> int:
|
||||
return BST.size(self)
|
||||
|
||||
func has_children() -> bool:
|
||||
return BST.has_children(self)
|
||||
|
||||
func balance() -> _Node:
|
||||
return BST.balance(self).unwrap()
|
||||
|
||||
func insert(value: int) -> _Node:
|
||||
return BST.insert(self, value)
|
||||
|
||||
func search(value: int) -> Option:
|
||||
return BST.search(self, value)
|
||||
|
||||
func remove(value: int) -> Option:
|
||||
return BST.remove(self, value)
|
||||
|
||||
func iter() -> Iterator:
|
||||
return BST.iter(self)
|
||||
|
||||
static func from(value: int) -> _Node:
|
||||
return _Node.new(value)
|
||||
|
||||
static func size(node: _Node) -> int:
|
||||
var left = node.left.map(size).or_default(0)
|
||||
var right = node.right.map(size).or_default(0)
|
||||
return left + right + 1
|
||||
|
||||
static func _store_in_order(_root: Option, nodes: Array[_Node] = []):
|
||||
if _root.is_none(): return
|
||||
|
||||
var root = _root.unwrap()
|
||||
_store_in_order(root.left, nodes)
|
||||
nodes.append(root)
|
||||
_store_in_order(root.right, nodes)
|
||||
|
||||
static func _build_balanced_tree(nodes: Array[_Node], start: int = 0, end: int = len(nodes) - 1) -> Option:
|
||||
if start > end:
|
||||
return Option.none
|
||||
|
||||
var mid: int = (start + end) / 2
|
||||
var root = nodes[mid]
|
||||
|
||||
root.left = _build_balanced_tree(nodes, start, mid - 1)
|
||||
root.right = _build_balanced_tree(nodes, mid + 1, end)
|
||||
|
||||
return Option.some(root)
|
||||
|
||||
static func balance(root: _Node) -> Option:
|
||||
var nodes: Array[_Node] = []
|
||||
_store_in_order(Option.some(root), nodes)
|
||||
return _build_balanced_tree(nodes, 0, len(nodes) - 1)
|
||||
|
||||
static func has_children(node: _Node) -> bool:
|
||||
return node.left.is_none() and node.right.is_none()
|
||||
|
||||
static func _insert(_root: Option, node: _Node) -> _Node:
|
||||
if _root.is_none(): return node
|
||||
|
||||
var root = _root.unwrap()
|
||||
if root.value == node.value: return root
|
||||
elif root.value < node.value:
|
||||
root.right = Option.some(_insert(root.right, node))
|
||||
else:
|
||||
root.left = Option.some(_insert(root.left, node))
|
||||
return root
|
||||
|
||||
static func insert(root: _Node, value: int) -> _Node:
|
||||
return _insert(Option.some(root), _Node.new(value))
|
||||
|
||||
static func _search(_root: Option, value: int) -> Option:
|
||||
if _root.is_none():
|
||||
return Option.none
|
||||
var root = _root.unwrap()
|
||||
if root.value == value:
|
||||
return _root
|
||||
if root.value < value:
|
||||
return _search(root.right, value)
|
||||
return _search(root.left, value)
|
||||
|
||||
static func search(root: _Node, value: int) -> Option:
|
||||
return _search(Option.some(root), value)
|
||||
|
||||
static func _get_successor(node: _Node) -> _Node:
|
||||
var current = node.right
|
||||
while current.is_some() and current.left.is_some():
|
||||
current = node.left.unwrap()
|
||||
return current
|
||||
|
||||
static func _remove(_root: Option, value: int) -> Option:
|
||||
if _root.is_none(): return _root
|
||||
|
||||
var root = _root.unwrap()
|
||||
if root.value < value:
|
||||
return _remove(root.right, value)
|
||||
elif root.value > value:
|
||||
return _remove(root.left, value)
|
||||
else:
|
||||
if root.right.is_none():
|
||||
return root.left
|
||||
elif root.left.is_none():
|
||||
return root.right
|
||||
|
||||
var successor = _get_successor(root)
|
||||
root.value = successor.value
|
||||
root.right = remove(root.right, successor.value)
|
||||
|
||||
return Option.some(root)
|
||||
|
||||
static func remove(root: _Node, value: int) -> Option:
|
||||
return _remove(Option.some(root), value)
|
||||
|
||||
static func traverse(root: _Node, fn: Callable):
|
||||
root.left.map(fn.call)
|
||||
fn.call(root.value)
|
||||
root.right.map(fn.call)
|
||||
|
||||
static func iter(node: _Node) -> Iterator:
|
||||
var iters = Option.collect_some([
|
||||
node.left.map(iter),
|
||||
Option.some(SingletonIterator.new(node.value)),
|
||||
node.right.map(iter)
|
||||
], true).unwrap()
|
||||
|
||||
var iter_arr: Array[Iterator]
|
||||
iter_arr.assign(iters)
|
||||
|
||||
return FusedIterator.new(iter_arr)
|
54
godot/addons/collections/int_range.gd
Normal file
54
godot/addons/collections/int_range.gd
Normal file
|
@ -0,0 +1,54 @@
|
|||
class_name IntRange extends RefCounted
|
||||
|
||||
var min: int
|
||||
var max: int
|
||||
|
||||
static var Zero = IntRange.new(0, 0)
|
||||
|
||||
func _init(start: int, end: int, inclusive: bool = false) -> void:
|
||||
min = start
|
||||
max = end if not inclusive else end + 1
|
||||
|
||||
func length() -> int:
|
||||
return absi(max - min)
|
||||
|
||||
func is_zero() -> bool:
|
||||
return min == 0 and max == 0
|
||||
|
||||
func is_empty() -> bool:
|
||||
return is_zero()
|
||||
|
||||
func iter(step: int = 1) -> RangeIterator:
|
||||
return RangeIterator.new(self, min, step)
|
||||
|
||||
func clamp(value: int) -> int:
|
||||
return clampi(value, min, max)
|
||||
|
||||
func wrap(value: int) -> int:
|
||||
return wrapi(value, min, max)
|
||||
|
||||
func contains(value: int) -> bool:
|
||||
return value >= min and value < max
|
||||
|
||||
func is_superset_of(range: IntRange) -> bool:
|
||||
return contains(range.min) and contains(range.max)
|
||||
|
||||
func is_subset_of(range: IntRange) -> bool:
|
||||
return range.is_superset_of(self)
|
||||
|
||||
func overlaps(range: IntRange) -> bool:
|
||||
return contains(range.min) or range.contains(min) or contains(range.max) or range.contains(max)
|
||||
|
||||
func difference(other: IntRange) -> Set:
|
||||
if is_subset_of(other):
|
||||
return Set.empty()
|
||||
elif not overlaps(other):
|
||||
return Set.from_iter(iter())
|
||||
|
||||
return Set.from_iter(iter()).difference(Set.from_iter(other.iter()))
|
||||
|
||||
func union(other: IntRange) -> Set:
|
||||
return Set.from_iter(iter()).union(Set.from_iter(other.iter()))
|
||||
|
||||
func intersect(other: IntRange) -> Set:
|
||||
return Set.from_iter(iter()).intersect(Set.from_iter(other.iter()))
|
89
godot/addons/collections/set.gd
Normal file
89
godot/addons/collections/set.gd
Normal file
|
@ -0,0 +1,89 @@
|
|||
class_name Set extends BST._Node
|
||||
|
||||
var data: Variant
|
||||
|
||||
func _init(data: Variant = null) -> void:
|
||||
super(_get_value(data))
|
||||
self.data = data
|
||||
|
||||
static func _get_value(value: Variant) -> int:
|
||||
match typeof(value):
|
||||
TYPE_NIL: return -1
|
||||
TYPE_INT: return value
|
||||
_: return hash(value)
|
||||
|
||||
static func empty() -> Set:
|
||||
return Set.new(null)
|
||||
|
||||
static func from_iter(iter: Variant) -> Set:
|
||||
var nodes: Array[_Node] = []
|
||||
for value in iter:
|
||||
nodes.append(Set.new(value))
|
||||
return BST._build_balanced_tree(nodes).unwrap()
|
||||
|
||||
func is_empty() -> bool:
|
||||
return value == -1 and not has_children()
|
||||
|
||||
func contains(data: Variant) -> bool:
|
||||
return BST.search(self, _get_value(data)).is_some()
|
||||
|
||||
func insert(data: Variant) -> _Node:
|
||||
if is_empty():
|
||||
self.value = _get_value(data)
|
||||
self.data = data
|
||||
return self
|
||||
elif not contains(data):
|
||||
return BST._insert(Option.some(self), Set.new(data))
|
||||
else:
|
||||
return self
|
||||
|
||||
func remove(data: Variant) -> Option:
|
||||
return BST.remove(self, _get_value(data))
|
||||
|
||||
func get(data: Variant) -> Option:
|
||||
return BST.search(self, _get_value(data)).map(func(x: Set) -> Variant: return x.data)
|
||||
|
||||
func equals(other: Set) -> bool:
|
||||
if not size() == other.size(): return false
|
||||
|
||||
for value in iter():
|
||||
if not other.contains(value): return false
|
||||
|
||||
return true
|
||||
|
||||
func union(other: Set) -> Set:
|
||||
var u = Set.from_iter(iter())
|
||||
for value in other.iter():
|
||||
u.insert(value)
|
||||
return u.balance()
|
||||
|
||||
func intersect(other: Set) -> Set:
|
||||
var i = Set.empty()
|
||||
for value in iter():
|
||||
if other.contains(value):
|
||||
i.insert(value)
|
||||
return i.balance()
|
||||
|
||||
func difference(other: Set) -> Set:
|
||||
if self.is_empty(): return Set.empty()
|
||||
elif other.is_empty(): return Set.from_iter(iter())
|
||||
var diff = Set.empty()
|
||||
for value in iter():
|
||||
if not other.contains(value):
|
||||
diff.insert(value)
|
||||
return diff.balance()
|
||||
|
||||
static func _iter(set: Set) -> Iterator:
|
||||
var iters = Option.collect_some([
|
||||
set.left.map(_iter),
|
||||
Option.none if set.value == -1 else Option.some(SingletonIterator.new(set.data)),
|
||||
set.right.map(_iter)
|
||||
], true).unwrap()
|
||||
|
||||
var iter_arr: Array[Iterator]
|
||||
iter_arr.assign(iters)
|
||||
|
||||
return FusedIterator.new(iter_arr)
|
||||
|
||||
func iter() -> Iterator:
|
||||
return _iter(self)
|
|
@ -16,7 +16,8 @@ func next() -> Option:
|
|||
if _index >= len(_iters): return Option.none
|
||||
|
||||
match _iters[_index].next():
|
||||
var value when value.is_some(): return value
|
||||
var value when value.is_some():
|
||||
return value
|
||||
_:
|
||||
_index += 1
|
||||
return next()
|
||||
|
|
14
godot/addons/iterator/singleton.gd
Normal file
14
godot/addons/iterator/singleton.gd
Normal file
|
@ -0,0 +1,14 @@
|
|||
class_name SingletonIterator extends Iterator
|
||||
|
||||
var value: Variant
|
||||
var emitted: bool = false
|
||||
|
||||
func _init(value: Variant) -> void:
|
||||
self.value = value
|
||||
|
||||
func next() -> Option:
|
||||
if not emitted:
|
||||
emitted = true
|
||||
return Option.some(value)
|
||||
else:
|
||||
return Option.none
|
|
@ -7,12 +7,12 @@ static func some(value: Variant) -> Option:
|
|||
|
||||
static var none: Option.None = None.new()
|
||||
|
||||
static func collect_some(options: Array[Option]) -> Option:
|
||||
static func collect_some(options: Array[Option], ignore_none: bool = false) -> Option:
|
||||
var result = []
|
||||
for option in options:
|
||||
if option.is_some():
|
||||
result.push_back(option.unwrap())
|
||||
else:
|
||||
elif not ignore_none:
|
||||
return Option.none
|
||||
return Option.some(result)
|
||||
|
||||
|
|
|
@ -8,20 +8,16 @@ static func ok(value: Variant) -> Result:
|
|||
static func err(error: Variant) -> Result:
|
||||
return Err.new(error)
|
||||
|
||||
static func collect_ok(results: Array[Result]) -> Result:
|
||||
match results:
|
||||
[]: return Result.Unit
|
||||
[var x]: return x
|
||||
_:
|
||||
var res = []
|
||||
static func collect_ok(results: Array[Result], ignore_err: bool = false) -> Result:
|
||||
var res = []
|
||||
|
||||
for result in results:
|
||||
if result.is_ok():
|
||||
res.push_back(result.unwrap())
|
||||
else:
|
||||
return result
|
||||
for result in results:
|
||||
if result.is_ok():
|
||||
res.push_back(result.unwrap())
|
||||
elif not ignore_err:
|
||||
return result
|
||||
|
||||
return Result.ok(res)
|
||||
return Result.ok(res)
|
||||
|
||||
class Ok extends Result:
|
||||
var value: Variant
|
||||
|
|
|
@ -1,20 +0,0 @@
|
|||
class_name IntRange extends RefCounted
|
||||
|
||||
var min: int
|
||||
var max: int
|
||||
|
||||
func _init(start: int, end: int, inclusive: bool = false) -> void:
|
||||
min = start
|
||||
max = end if not inclusive else end + 1
|
||||
|
||||
func length() -> int:
|
||||
return absi(max - min)
|
||||
|
||||
func clamp(value: int) -> int:
|
||||
return clampi(value, min, max)
|
||||
|
||||
func wrap(value: int) -> int:
|
||||
return wrapi(value, min, max)
|
||||
|
||||
func contains(value: int) -> bool:
|
||||
return value >= min and value < max
|
|
@ -11,10 +11,14 @@ var bind_item: Callable = _bind_item
|
|||
var ring_buffer: RingBuffer
|
||||
|
||||
func _ready() -> void:
|
||||
var a = IntRange.new(0, 6)
|
||||
var b = IntRange.new(5, 7)
|
||||
for value in a.difference(b).iter():
|
||||
print(value)
|
||||
ring_buffer = RingBuffer.new(items.size(), buffer_size)
|
||||
ring_buffer.updated.connect(_on_updated)
|
||||
|
||||
for _i in range(max_items):
|
||||
for _i in range(buffer_size):
|
||||
add_child(create_item.call())
|
||||
|
||||
func _create_item() -> Node:
|
||||
|
@ -30,8 +34,8 @@ func _on_updated(_current_range: IntRange, _previous_range: IntRange):
|
|||
func _update_display():
|
||||
var indices: Array = ring_buffer.range().collect()
|
||||
|
||||
for i in range(min(indices.size(), ring_buffer.capacity)):
|
||||
var node = get_child(i)
|
||||
for i in range(min(indices.size(), max_items)):
|
||||
var node = get_child(i + 1)
|
||||
var item = items[indices[i]]
|
||||
bind_item.call(node, item)
|
||||
|
||||
|
@ -44,32 +48,3 @@ func add_items(new_items: Array):
|
|||
items.append_array(new_items)
|
||||
ring_buffer.source_size = items.size()
|
||||
_update_display()
|
||||
|
||||
|
||||
# inventory ui
|
||||
# two parts
|
||||
# * list of items
|
||||
# * selected item details
|
||||
#
|
||||
# list of items is a window into the inventory
|
||||
# eg. a list of 5 items with a ui that can display 3 where the third item is selected:
|
||||
# [1, (2, 3, 4), 5]
|
||||
#
|
||||
# add_item(item):
|
||||
# append item to item array
|
||||
# if new index occurs in display window:
|
||||
# bind element
|
||||
|
||||
# remove_item(item):
|
||||
# index = find index
|
||||
# remove_index(index)
|
||||
|
||||
# remove_index(index):
|
||||
# remove item at index
|
||||
|
||||
# move(direction):
|
||||
# if direction is left:
|
||||
# move last element to first
|
||||
# else:
|
||||
# move first element to last
|
||||
# bind new element
|
||||
|
|
Loading…
Add table
Reference in a new issue