extends RefCounted
class_name BrushShapes
## THE SHAPE REGISTRY the create tool cycles (editor redesign E4, docs/editor-redesign.md §8b).
##
## Built-ins first, in this order, because CreateBoxOperator.Shape {BOX, STAIRS, ARCH}
## are indices into it and saved gates set them by number. Plugins append; Tab cycles
## the whole list. Ids are durable (they are the sticky pref), so never rename one.
static var _list: Array = []
static func all() -> Array:
_ensure()
return _list
static func count() -> int:
_ensure()
return _list.size()
static func at(i: int) -> BrushShape:
_ensure()
return _list[posmod(i, _list.size())] as BrushShape
static func index_of(sid: String) -> int:
_ensure()
for i in _list.size():
if (_list[i] as BrushShape).id() == sid:
return i
return -1
## Add a shape. Replaces one with the same id, so a plugin reloading does not stack.
static func register(shape: BrushShape) -> int:
_ensure()
var i := index_of(shape.id())
if i >= 0:
_list[i] = shape
return i
_list.append(shape)
return _list.size() - 1
## Remove a plugin shape (a gate cleans up after itself). Built-ins stay.
static func unregister(sid: String) -> void:
var i := index_of(sid)
if i >= BUILTIN_COUNT:
_list.remove_at(i)
## Built-ins, in this order (box / stairs / arch are CreateBoxOperator.Shape indices and
## must stay first). Cylinder / cone / sphere are TrenchBroom's BasicShapes (#31).
const BUILTIN_COUNT := 6
static func _ensure() -> void:
if _list.is_empty():
_list = [BoxShape.new(), StairsShape.new(), ArchShape.new(),
CylinderShape.new(), ConeShape.new(), SphereShape.new()]