Search Apps Documentation Source Content File Folder Download Copy Actions Download State String Boolean Number Struct Map Slice Pointer Function Closure Reference Nil Package Type Interface Unknown

activity.gno

2.48 Kb · 80 lines
 1package radio
 2
 3import (
 4	"strings"
 5
 6	"gno.land/p/nym-alexiscolin000/gnoradio/store/v0"
 7	"gno.land/p/nym-alexiscolin000/gnoradio/text/v0"
 8)
 9
10const activitySize = 64
11
12// Activity is one programming action on a station.
13type Activity struct {
14	Kind    string // queue | curator | sponsored
15	By      address
16	Track   int
17	Station int
18	Start   int64
19	At      int64
20}
21
22// recordActivity writes the next slot of the fixed-size ring (storage
23// never grows): Rec(kind, by, numbers), the numbers the track (4 digits),
24// the station (1), the start (6) and the time (6). The head is in the flow
25// record.
26func recordActivity(t *tx, kind string, by address, track, station int, start int64) {
27	h := t.flowAt(fHead, 1)
28	n := store.AppendFixed(store.AppendFixed(store.AppendFixed(store.AppendFixed(make([]byte, 0, 17), int64(track), 4), int64(station), 1), start, 6), now(), 6)
29	t.put(cActivity, store.Pad(h), store.Rec(kind, by.String(), string(n)))
30	t.setFlowAt(fHead, 1, (h+1)%activitySize)
31}
32
33func activityOf(rec string) Activity {
34	f := store.Fields(rec)
35	n := f[2]
36	return Activity{Kind: f[0], By: address(f[1]), Track: int(store.Num(n, 0, 4)), Station: int(store.Num(n, 4, 1)), Start: store.Num(n, 5, 6), At: store.Num(n, 11, 6)}
37}
38
39// activities returns up to limit records, newest first: the ring's slots
40// before its head, read one by one (the ring fills from slot 0 and no slot
41// is ever deleted, so the first empty one ends it).
42func activities(limit int) []string {
43	limit = store.Limit(limit, activitySize)
44	t := rd()
45	head := t.flowAt(fHead, 1)
46	out := make([]string, 0, limit)
47	for i := 1; i <= limit; i++ {
48		rec := t.val(cActivity, store.Pad((head-i+activitySize)%activitySize))
49		if rec == "" {
50			break // the ring is not full yet
51		}
52		out = append(out, rec)
53	}
54	return out
55}
56
57// Activities returns up to limit entries, newest first.
58func Activities(limit int) []Activity {
59	var out []Activity
60	for _, rec := range activities(limit) {
61		out = append(out, activityOf(rec))
62	}
63	return out
64}
65
66// ActivityJSON returns the programming feed, newest first (limit <= 64).
67func ActivityJSON(limit int) string {
68	var b strings.Builder
69	b.WriteString("[")
70	for i, rec := range activities(limit) {
71		a := activityOf(rec)
72		if i > 0 {
73			b.WriteString(",")
74		}
75		b.WriteString(`{"kind":` + text.Str(a.Kind) + `,"by":` + text.Str(a.By.String()) + `,"track":` + text.Itoa(a.Track) +
76			`,"station":` + text.Itoa(a.Station) + `,"start":` + text.Itoa64(a.Start) + `,"at":` + text.Itoa64(a.At) + `}`)
77	}
78	b.WriteString("]")
79	return b.String()
80}