diff --git a/firefly/net.go b/firefly/net.go index cfab90f..7a02ab7 100644 --- a/firefly/net.go +++ b/firefly/net.go @@ -108,6 +108,11 @@ func (peers Peers) Iter() iter.Seq[Peer] { } } +// Get a scanner of the peers, allowing iterating over them without any allocations. +func (peers Peers) Scanner() PeerScanner { + return PeerScanner{peers: peers} +} + // Check if the given [Peer] is online. func (peers Peers) Contains(peer Peer) bool { return peers.p>>peer.raw&1 != 0 @@ -134,6 +139,32 @@ func GetPeers() Peers { return Peers{getPeers()} } +// Scanner used to iterate a list of peers without any allocations. +// +// Can be obtained using [Peers.NewScanner]. +type PeerScanner struct { + peers Peers + nextID uint8 +} + +// Find the next peer. Use [PeerScanner.Peer] to get the current value. +func (s *PeerScanner) Scan() bool { + for s.nextID < 32 { + if s.peers.Contains(Peer{s.nextID}) { + s.nextID++ + return true + } + s.nextID++ + } + return false +} + +// Current scanned peer. Calling this function before [PeerScanner.Scan] +// is considered undefined behavior. +func (s *PeerScanner) Peer() Peer { + return Peer{s.nextID - 1} +} + // Save the given [Stash]. // // When called, the stash for the given peer will be stored in RAM. diff --git a/firefly/net_example_test.go b/firefly/net_example_test.go new file mode 100644 index 0000000..ad79a8c --- /dev/null +++ b/firefly/net_example_test.go @@ -0,0 +1,11 @@ +package firefly_test + +import "github.com/firefly-zero/firefly-go/firefly" + +func ExamplePeers_Scanner() { + scanner := firefly.GetPeers().Scanner() + for scanner.Scan() { + peer := scanner.Peer() + _ = peer + } +}