diff options
Diffstat (limited to 'objreg.ha')
-rw-r--r-- | objreg.ha | 64 |
1 files changed, 64 insertions, 0 deletions
diff --git a/objreg.ha b/objreg.ha new file mode 100644 index 0000000..2630328 --- /dev/null +++ b/objreg.ha @@ -0,0 +1,64 @@ +use hash::fnv; +use htab; + +type ObjectRegistry = struct { + table: htab::table, // *Object +}; + +type Object = struct { + name: str, +}; + +def OBJREG_EMPTY = ObjectRegistry { + table = HTAB_EMPTY, +}; + +fn newobjreg() ObjectRegistry = + ObjectRegistry { + table = htab::new(0, size(*Object)), + }; + +fn objreg_eqfunc(ctx: *opaque, entry: *opaque) bool = + return *(ctx: *str) == (entry: **Object).name; + +fn objreg_find(reg: *ObjectRegistry, name: str) nullable *opaque = { + const hash = fnv::string64(name); + match (htab::get(®.table, hash, + &objreg_eqfunc, &name, size(*Object))) { + case let entry: *opaque => + return *(entry: **Object); + case null => + return null; + }; +}; + +fn objreg_register(reg: *ObjectRegistry, obj: *Object) void = { + assert(objreg_find(reg, obj.name) == null, "already registered"); + const hash = fnv::string64(obj.name); + const entry = htab::add(®.table, hash, size(*Object)); + *(entry: **Object) = obj; +}; + +fn objreg_count(reg: *ObjectRegistry) size = + htab::count(®.table); + +fn objreg_clear(reg: *ObjectRegistry) void = + htab::clear(®.table, size(*Object)); + +type ObjectRegistryIterator = struct { + inner: htab::iterator, +}; + +fn objreg_iter(reg: *ObjectRegistry) ObjectRegistryIterator = + ObjectRegistryIterator { + inner = htab::iter(®.table), + }; + +fn objreg_next(it: *ObjectRegistryIterator) nullable *Object = { + match (htab::next(&it.inner, size(*Object))) { + case let entry: *opaque => + return *(entry: **Object); + case null => + return null; + }; +}; |