summaryrefslogtreecommitdiff
path: root/client/object
diff options
context:
space:
mode:
authorcitrons <citrons@mondecitronne.com>2025-05-30 17:47:35 -0500
committercitrons <citrons@mondecitronne.com>2025-05-30 17:47:35 -0500
commitb3a01b28cbfe43ef22168a2f81803dccd4e56864 (patch)
tree042a79f70fe1b6f08bc3ba6b0ea2dde127b1a1be /client/object
parent194c63381a8b19f6a9198ff30a307b65acc2af76 (diff)
simple client
Diffstat (limited to 'client/object')
-rw-r--r--client/object/object.go95
1 files changed, 95 insertions, 0 deletions
diff --git a/client/object/object.go b/client/object/object.go
new file mode 100644
index 0000000..f42eaf8
--- /dev/null
+++ b/client/object/object.go
@@ -0,0 +1,95 @@
+package object
+
+import (
+ "citrons.xyz/talk/proto"
+)
+
+type ObjCache struct {
+ stream ObjStream
+ objects map[string]cacheEntry
+}
+
+type cacheEntry struct {
+ o proto.Object
+ refCount int
+ cached bool
+}
+
+type ObjStream interface {
+ Sub(id string)
+ GetInfo(id string, callback func(proto.Command))
+ Unsub(id string)
+}
+
+func NewCache(stream ObjStream) ObjCache {
+ return ObjCache {stream, make(map[string]cacheEntry)}
+}
+
+func (oc *ObjCache) Get(id string) *proto.Object {
+ entry := oc.objects[id]
+ if !entry.cached {
+ return nil
+ }
+ return &entry.o
+}
+
+func (oc *ObjCache) Fetch(id string, callback func(*proto.Object)) {
+ entry := oc.objects[id]
+ if !entry.cached {
+ oc.stream.GetInfo(id, func(cmd proto.Command) {
+ if cmd.Kind == "i" && len(cmd.Args) > 0 {
+ callback(&cmd.Args[0])
+ } else {
+ callback(nil)
+ }
+ })
+ }
+ callback(&entry.o)
+}
+
+func (oc *ObjCache) Watch(id string) {
+ entry, ok := oc.objects[id]
+ if !ok {
+ oc.stream.Sub(id)
+ }
+ oc.objects[id] = entry
+}
+
+func (oc *ObjCache) Unwatch(id string) {
+ entry, ok := oc.objects[id]
+ if ok {
+ entry.refCount--
+ if entry.refCount <= 0 {
+ oc.stream.Unsub(id)
+ delete(oc.objects, id)
+ } else {
+ oc.objects[id] = entry
+ }
+ }
+}
+
+func (oc *ObjCache) Update(id string, new proto.Object) {
+ entry := oc.objects[id]
+ if entry.cached && new.Kind == entry.o.Kind {
+ for k, v := range new.Fields {
+ entry.o.Fields[k] = v
+ }
+ } else {
+ entry.o = new
+ }
+ entry.cached = true
+ oc.objects[id] = entry
+}
+
+func (oc *ObjCache) Gone(id string) {
+ entry := oc.objects[id]
+ if entry.cached {
+ obj := entry.o
+ obj.Fields["kind"] = obj.Kind
+ obj.Kind = "gone"
+ entry.o = obj
+ oc.objects[id] = entry
+ }
+}
+
+