Skip to content

Commit

Permalink
change struct to make it similar to before
Browse files Browse the repository at this point in the history
  • Loading branch information
kelindar committed Nov 12, 2024
1 parent 38c4b81 commit cf69df0
Show file tree
Hide file tree
Showing 3 changed files with 70 additions and 102 deletions.
30 changes: 14 additions & 16 deletions grid.go
Original file line number Diff line number Diff line change
Expand Up @@ -256,11 +256,11 @@ func (p *page[T]) writeTile(grid *Grid[T], idx uint8, after Value) {
if p.IsObserved() {
at := pointOf(p.point, idx)
grid.observers.Notify1(&Update[T]{
Old: UpdateState[T]{
Old: ValueAt{
Point: at,
Value: before,
},
New: UpdateState[T]{
New: ValueAt{
Point: at,
Value: after,
},
Expand All @@ -283,11 +283,11 @@ func (p *page[T]) mergeTile(grid *Grid[T], idx uint8, fn func(Value) Value) Valu
if p.IsObserved() {
at := pointOf(p.point, idx)
grid.observers.Notify1(&Update[T]{
Old: UpdateState[T]{
Old: ValueAt{
Point: at,
Value: before,
},
New: UpdateState[T]{
New: ValueAt{
Point: at,
Value: after,
},
Expand Down Expand Up @@ -385,16 +385,15 @@ func (t Tile[T]) Add(v T) {
if t.data.IsObserved() {
at := t.Point()
t.grid.observers.Notify1(&Update[T]{
Old: UpdateState[T]{
Old: ValueAt{
Point: at,
Value: value,
Add: v,
},
New: UpdateState[T]{
New: ValueAt{
Point: at,
Value: value,
Add: v,
},
Add: v,
}, t.data.point, at)
}
}
Expand All @@ -407,16 +406,15 @@ func (t Tile[T]) Del(v T) {
if t.data.IsObserved() {
at := t.Point()
t.grid.observers.Notify1(&Update[T]{
Old: UpdateState[T]{
Old: ValueAt{
Point: at,
Value: value,
Del: v,
},
New: UpdateState[T]{
New: ValueAt{
Point: at,
Value: value,
Del: v,
},
Del: v,
}, t.data.point, at)
}
}
Expand All @@ -437,16 +435,16 @@ func (t Tile[T]) Move(v T, dst Point) bool {

// Prepare the update notification
update := &Update[T]{
Old: UpdateState[T]{
Old: ValueAt{
Point: t.Point(),
Value: tv,
Del: v,
},
New: UpdateState[T]{
New: ValueAt{
Point: d.Point(),
Value: dv,
Add: v,
},
Del: v,
Add: v,
}

switch {
Expand Down
87 changes: 27 additions & 60 deletions view.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,18 +15,18 @@ type Observer[T comparable] interface {
onUpdate(*Update[T])
}

type UpdateState[T comparable] struct {
Point // The point of the tile
Value // The value of the tile
Add T // An object was added to the tile
Del T // An object was removed from the tile
// ValueAt represents a tile and its value.
type ValueAt struct {
Point // The point of the tile
Value // The value of the tile
}

// Update represents a tile update notification.
type Update[T comparable] struct {
Old UpdateState[T] // Old tile + value
New UpdateState[T] // New tile + value

Old ValueAt // Old tile + value
New ValueAt // New tile + value
Add T // An object was added to the tile
Del T // An object was removed from the tile
}

var _ Observer[string] = (*View[string, string])(nil)
Expand Down Expand Up @@ -171,6 +171,25 @@ type pubsub[T comparable] struct {
tmp sync.Pool // Temporary observer sets for notifications
}

// Subscribe registers an event listener on a system
func (p *pubsub[T]) Subscribe(page Point, sub Observer[T]) bool {
if v, ok := p.m.Load(page.Integer()); ok {
return v.(*observers[T]).Subscribe(sub)
}

// Slow path
v, _ := p.m.LoadOrStore(page.Integer(), newObservers[T]())
return v.(*observers[T]).Subscribe(sub)
}

// Unsubscribe deregisters an event listener from a system
func (p *pubsub[T]) Unsubscribe(page Point, sub Observer[T]) bool {
if v, ok := p.m.Load(page.Integer()); ok {
return v.(*observers[T]).Unsubscribe(sub)
}
return false
}

// Notify notifies listeners of an update that happened.
func (p *pubsub[T]) Notify1(ev *Update[T], page, at Point) {
p.Each1(func(sub Observer[T]) {
Expand Down Expand Up @@ -219,58 +238,6 @@ func (p *pubsub[T]) Each2(fn func(sub Observer[T]), pages, locs [2]Point) {
}
}

/*
// Each iterates over each observer in a page
func (p *pubsub[T]) Each(fn func(sub Observer[T]), pages ...Point) {
switch len(pages) {
// Single page: directly invoke the callback
case 1:
if v, ok := p.m.Load(pages[0].Integer()); ok {
v.(*observers[T]).Each(fn)
}
// Multiple pages: merge distinct observers and invoke the callback
default:
targets := p.tmp.Get().(map[Observer[T]]struct{})
clear(targets)
defer p.tmp.Put(targets)
// Collect all observers from all pages
for _, page := range pages {
if v, ok := p.m.Load(page.Integer()); ok {
v.(*observers[T]).Each(func(sub Observer[T]) {
targets[sub] = struct{}{}
})
}
}
// Invoke the callback for each observer, once
for sub := range targets {
fn(sub)
}
}
}*/

// Subscribe registers an event listener on a system
func (p *pubsub[T]) Subscribe(page Point, sub Observer[T]) bool {
if v, ok := p.m.Load(page.Integer()); ok {
return v.(*observers[T]).Subscribe(sub)
}

// Slow path
v, _ := p.m.LoadOrStore(page.Integer(), newObservers[T]())
return v.(*observers[T]).Subscribe(sub)
}

// Unsubscribe deregisters an event listener from a system
func (p *pubsub[T]) Unsubscribe(page Point, sub Observer[T]) bool {
if v, ok := p.m.Load(page.Integer()); ok {
return v.(*observers[T]).Unsubscribe(sub)
}
return false
}

// -----------------------------------------------------------------------------

// Observers represents a change notifier which notifies the subscribers when
Expand Down
55 changes: 29 additions & 26 deletions view_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ package tile

import (
"testing"
"unsafe"

"github.com/stretchr/testify/assert"
)
Expand Down Expand Up @@ -143,10 +144,10 @@ func TestUpdates_Simple(t *testing.T) {
cursor, _ := v.At(5, 5)
cursor.Write(Value(0xF0))
assert.Equal(t, Update[string]{
Old: UpdateState[string]{
Old: ValueAt{
Point: At(5, 5),
},
New: UpdateState[string]{
New: ValueAt{
Point: At(5, 5),
Value: Value(0xF0),
},
Expand All @@ -155,41 +156,39 @@ func TestUpdates_Simple(t *testing.T) {
// Add an object to an observed tile
cursor.Add("A")
assert.Equal(t, Update[string]{
Old: UpdateState[string]{
Old: ValueAt{
Point: At(5, 5),
Value: Value(0xF0),
Add: "A",
},
New: UpdateState[string]{
New: ValueAt{
Point: At(5, 5),
Value: Value(0xF0),
Add: "A",
},
Add: "A",
}, <-v.Inbox)

// Delete an object from an observed tile
cursor.Del("A")
assert.Equal(t, Update[string]{
Old: UpdateState[string]{
Old: ValueAt{
Point: At(5, 5),
Value: Value(0xF0),
Del: "A",
},
New: UpdateState[string]{
New: ValueAt{
Point: At(5, 5),
Value: Value(0xF0),
Del: "A",
},
Del: "A",
}, <-v.Inbox)

// Mask a tile in view
cursor.Mask(0xFF, 0x0F)
assert.Equal(t, Update[string]{
Old: UpdateState[string]{
Old: ValueAt{
Point: At(5, 5),
Value: Value(0xF0),
},
New: UpdateState[string]{
New: ValueAt{
Point: At(5, 5),
Value: Value(0xFF),
},
Expand All @@ -200,11 +199,11 @@ func TestUpdates_Simple(t *testing.T) {
return 0xAA
})
assert.Equal(t, Update[string]{
Old: UpdateState[string]{
Old: ValueAt{
Point: At(5, 5),
Value: Value(0xFF),
},
New: UpdateState[string]{
New: ValueAt{
Point: At(5, 5),
Value: Value(0xAA),
},
Expand All @@ -222,14 +221,14 @@ func TestMove_Within(t *testing.T) {
cursor, _ := v.At(5, 5)
cursor.Move("A", At(6, 6))
assert.Equal(t, Update[string]{
Old: UpdateState[string]{
Old: ValueAt{
Point: At(5, 5),
Del: "A",
},
New: UpdateState[string]{
New: ValueAt{
Point: At(6, 6),
Add: "A",
},
Del: "A",
Add: "A",
}, <-v.Inbox)
}

Expand All @@ -243,14 +242,14 @@ func TestMove_Incoming(t *testing.T) {
cursor, _ := v.At(20, 20)
cursor.Move("A", At(5, 5))
assert.Equal(t, Update[string]{
Old: UpdateState[string]{
Old: ValueAt{
Point: At(20, 20),
Del: "A",
},
New: UpdateState[string]{
New: ValueAt{
Point: At(5, 5),
Add: "A",
},
Del: "A",
Add: "A",
}, <-v.Inbox)
}

Expand All @@ -264,14 +263,14 @@ func TestMove_Outgoing(t *testing.T) {
cursor, _ := v.At(5, 5)
cursor.Move("A", At(20, 20))
assert.Equal(t, Update[string]{
Old: UpdateState[string]{
Old: ValueAt{
Point: At(5, 5),
Del: "A",
},
New: UpdateState[string]{
New: ValueAt{
Point: At(20, 20),
Add: "A",
},
Del: "A",
Add: "A",
}, <-v.Inbox)
}

Expand Down Expand Up @@ -318,6 +317,10 @@ func TestView_MoveTo(t *testing.T) {
assert.NoError(t, v.Close())
}

func TestSizeUpdate(t *testing.T) {
assert.Equal(t, 24, int(unsafe.Sizeof(Update[uint32]{})))
}

// ---------------------------------- Mocks ----------------------------------

func countObserversAt(m *Grid[string], x, y int16) (count int) {
Expand Down

0 comments on commit cf69df0

Please sign in to comment.