Skip to content

Commit

Permalink
Merge pull request #12 from MattSScott/package-tidy
Browse files Browse the repository at this point in the history
tidied package code for final release
  • Loading branch information
MattSScott authored Sep 20, 2023
2 parents e37f7b0 + c7fe4d8 commit e34922f
Show file tree
Hide file tree
Showing 11 changed files with 134 additions and 83 deletions.
2 changes: 1 addition & 1 deletion main.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,5 @@ func main() {
iterations := 1
ts := testserver.New(m, iterations)

ts.RunGameLoop()
ts.Start()
}
6 changes: 4 additions & 2 deletions pkg/main/BaseAgent/agentInterface.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,10 @@ import (
)

type IAgent[T any] interface {
// composes messaging passing capabilities
message.IAgentMessenger[T]
Activity()
UpdateAgent()
// allows agent to update their internal state
UpdateAgentInternalState()
// returns the unique ID of an agent
GetID() uuid.UUID
}
24 changes: 1 addition & 23 deletions pkg/main/BaseAgent/baseAgent.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
package baseagent

import (
"fmt"

message "github.com/MattSScott/basePlatformSOMAS/pkg/main/messaging"
"github.com/google/uuid"
)
Expand All @@ -16,13 +14,7 @@ func (ba *BaseAgent[T]) GetID() uuid.UUID {
return ba.id
}

func (ba *BaseAgent[T]) UpdateAgent() {
fmt.Println("Updating BaseAgent...")
}

func (ba *BaseAgent[T]) Activity() {
fmt.Printf("id: %s\n", ba.GetID())
fmt.Println("__________________________")
func (ba *BaseAgent[T]) UpdateAgentInternalState() {
}

func NewAgent[T IAgent[T]]() *BaseAgent[T] {
Expand All @@ -31,12 +23,6 @@ func NewAgent[T IAgent[T]]() *BaseAgent[T] {
}
}

// func GetAgent[T IAgent[T]]() *BaseAgent[T] {
// return &BaseAgent[T]{
// id: uuid.New(),
// }
// }

func (ba *BaseAgent[T]) GetAllMessages() []message.IMessage[T] {
return []message.IMessage[T]{}
}
Expand All @@ -45,14 +31,6 @@ func (ba *BaseAgent[T]) GetNetwork() []T {
return ba.network
}

func (ba *BaseAgent[T]) GetNetworkForMessaging() []message.IAgentMessenger[T] {
messengerArray := make([]message.IAgentMessenger[T], len(ba.network))
for i := range ba.network {
messengerArray[i] = ba.network[i]
}
return messengerArray
}

func (ba *BaseAgent[T]) SetNetwork(newNetwork []T) {
ba.network = newNetwork
}
1 change: 1 addition & 0 deletions pkg/main/messaging/agentMessenger.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,6 @@ package messaging

// // base interface structure used for message passing - can be composed for more complex message structures
type IAgentMessenger[T any] interface {
// produces a list of messages (of any common interface) that an agent wishes to pass
GetAllMessages([]T) []IMessage[T]
}
20 changes: 7 additions & 13 deletions pkg/main/messaging/message.go
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
package messaging

// import baseagent "github.com/MattSScott/basePlatformSOMAS/pkg/agents/BaseAgent"

// base interface structure used for message passing - can be composed for more complex message structures

// new message types extend this
// base interface structure used for message - can be composed for more complex message structures
type IMessage[T any] interface {
// returns the sender of a message
GetSender() T
// returns the list of agents that the message should be passed to
GetRecipients() []T
Accept(T)
// calls the appropriate messsage handler method on the receiving agent
InvokeMessageHandler(T)
}

// new message types can extend this
type BaseMessage[T IAgentMessenger[T]] struct {
sender T
recipients []T
Expand All @@ -24,12 +24,6 @@ func CreateMessage[T IAgentMessenger[T]](sender T, recipients []T) BaseMessage[T
}
}

// func CreateNullMessageWithSender(sender IAgentMessenger) BaseMessage {
// return BaseMessage{
// sender: sender,
// }
// }

func (bm BaseMessage[T]) GetSender() T {
return bm.sender
}
Expand All @@ -38,5 +32,5 @@ func (bm BaseMessage[T]) GetRecipients() []T {
return bm.recipients
}

func (bm BaseMessage[T]) Accept(agent T) {
func (bm BaseMessage[T]) InvokeMessageHandler(agent T) {
}
12 changes: 6 additions & 6 deletions pkg/main/messaging/message_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,15 +35,15 @@ type ExtendedAgent struct {
agentField int
}

func (m1 Message1) Accept(agent IExtendedAgent) {
func (m1 Message1) InvokeMessageHandler(agent IExtendedAgent) {
agent.HandleMessage1(m1)
}

func (m2 Message2) Accept(agent IExtendedAgent) {
func (m2 Message2) InvokeMessageHandler(agent IExtendedAgent) {
agent.HandleMessage2(m2)
}

func (nm NullMessage) Accept(agent IExtendedAgent) {
func (nm NullMessage) InvokeMessageHandler(agent IExtendedAgent) {
agent.HandleNullMessage(nm)
}

Expand Down Expand Up @@ -91,10 +91,10 @@ func TestMessageCanBeExtended(t *testing.T) {
agent2 := &ExtendedAgent{agentField: 0}

msgFromA1 := agent1.GetMessage1()
msgFromA1.Accept(agent2)
msgFromA1.InvokeMessageHandler(agent2)

msgFromA2 := agent2.GetMessage2()
msgFromA2.Accept(agent1)
msgFromA2.InvokeMessageHandler(agent1)

if agent1.agentField != 10 {
t.Error("Message 2 not properly handled")
Expand All @@ -114,7 +114,7 @@ func TestMessageSender(t *testing.T) {
nullMsg := a1.GetNullMessage([]IExtendedAgent{a2, a3})

for _, recip := range nullMsg.GetRecipients() {
nullMsg.Accept(recip)
nullMsg.InvokeMessageHandler(recip)
}

if a1.GetAgentField() != a2.GetAgentField() || a3.GetAgentField() != a1.GetAgentField() {
Expand Down
52 changes: 30 additions & 22 deletions pkg/main/server/baseServer.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,29 +7,38 @@ import (
)

type BaseServer[T baseagent.IAgent[T]] struct {
NumAgents int
NumTurns int
Agents []T
numTurns int
agents []T
}

func (bs *BaseServer[T]) RunGameLoop() {
fmt.Printf("%d agents initialised: \n", bs.NumAgents)
for index, agent := range bs.Agents {
fmt.Printf("agent %d \n", index)
fmt.Printf("_____________________________________________ \n")
agent.UpdateAgent()
agent.Activity()
//TO DO: add the function for stages
func (bs *BaseServer[T]) GetAgents() []T {
return bs.agents
}

}
func (bs *BaseServer[T]) GetNumTurns() int {
return bs.numTurns
}

func (bs *BaseServer[T]) RunGameLoop() {
for _, agent := range bs.agents {
fmt.Printf("Agent %s updating state \n", agent.GetID())
agent.UpdateAgentInternalState()
}
}

func (bs *BaseServer[T]) Start() {
fmt.Printf("Server initialised with %d agents \n", len(bs.agents))
fmt.Print("\n")
//LOOPS
for i := 0; i < bs.NumTurns; i++ {
fmt.Printf("Game Loop %d Running \n", i)
for i := 0; i < bs.numTurns; i++ {
fmt.Printf("Game Loop %d running... \n \n", i)
fmt.Printf("Main game loop running... \n \n")
bs.RunGameLoop()
fmt.Printf("\nMain game loop finished. \n \n")
fmt.Printf("Messaging session started... \n \n")
bs.RunMessagingSession()
fmt.Printf("\nMessaging session completed \n \n")
fmt.Printf("Game Loop %d completed. \n", i)
}

}
Expand All @@ -49,15 +58,15 @@ func MakeAgentGeneratorCountPair[T baseagent.IAgent[T]](generatorFunction AgentG
}

func (bs *BaseServer[T]) RunMessagingSession() {
for _, agent := range bs.Agents {
allMessages := agent.GetAllMessages(bs.Agents)
for _, agent := range bs.agents {
allMessages := agent.GetAllMessages(bs.agents)
for _, msg := range allMessages {
recipients := msg.GetRecipients()
for _, recip := range recipients {
if agent.GetID() == recip.GetID() {
continue
}
msg.Accept(recip)
msg.InvokeMessageHandler(recip)
}
}
}
Expand All @@ -75,8 +84,7 @@ func (bs *BaseServer[T]) initialiseAgents(m []AgentGeneratorCountPair[T]) {
}
}

bs.Agents = agents
bs.NumAgents = len(agents)
bs.agents = agents
}

func getNumAgents[T baseagent.IAgent[T]](pairs []AgentGeneratorCountPair[T]) int {
Expand All @@ -90,10 +98,10 @@ func getNumAgents[T baseagent.IAgent[T]](pairs []AgentGeneratorCountPair[T]) int
return numAgents
}

func CreateServer[T baseagent.IAgent[T]](mapper []AgentGeneratorCountPair[T], numTurns int) *BaseServer[T] {
// generate the server and return it
// generate a server instance based on a mapping function and number of iterations
func CreateServer[T baseagent.IAgent[T]](mapper []AgentGeneratorCountPair[T], iterations int) *BaseServer[T] {
serv := &BaseServer[T]{
NumTurns: numTurns,
numTurns: iterations,
}
serv.initialiseAgents(mapper)
return serv
Expand Down
12 changes: 9 additions & 3 deletions pkg/main/server/serverInterface.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
package server

type IServer interface {
// the set of functions defining a 'game loop' should run
import baseagent "github.com/MattSScott/basePlatformSOMAS/pkg/main/BaseAgent"

type IServer[T baseagent.IAgent[T]] interface {
// the set of functions defining how a 'game loop' should run
RunGameLoop()
// runs simulator
// begins simulator
Start()
// gives access to the agents in the simulator
GetAgents() []T
// gives access to number of iteration in simulator
GetNumTurns() int
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ func (em *GreetingMessage) GetGreeting() string {
return em.greeting
}

func (em GreetingMessage) Accept(agent IExtendedAgent) {
func (em GreetingMessage) InvokeMessageHandler(agent IExtendedAgent) {
agent.HandleGreetingMessage(em)
}

Expand Down
49 changes: 48 additions & 1 deletion pkg/testing/testServer/server_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
helloagent "github.com/MattSScott/basePlatformSOMAS/pkg/testing/testAgents/helloAgent"
worldagent "github.com/MattSScott/basePlatformSOMAS/pkg/testing/testAgents/worldAgent"
testserver "github.com/MattSScott/basePlatformSOMAS/pkg/testing/testServer"
"github.com/google/uuid"

"testing"
)
Expand All @@ -20,7 +21,7 @@ func TestInheritedServer(t *testing.T) {
floors := 3
ts := testserver.New(m, floors)

if len(ts.Agents) != 5 {
if len(ts.GetAgents()) != 5 {
t.Error("Agents not properly instantiated")
}

Expand All @@ -31,3 +32,49 @@ func TestInheritedServer(t *testing.T) {
ts.RunGameLoop()
ts.Start()
}

func TestServerInterfaceComposition(t *testing.T) {

m := make([]server.AgentGeneratorCountPair[baseExtendedAgent.IExtendedAgent], 2)

m[0] = server.MakeAgentGeneratorCountPair[baseExtendedAgent.IExtendedAgent](helloagent.GetHelloAgent, 1)
m[1] = server.MakeAgentGeneratorCountPair[baseExtendedAgent.IExtendedAgent](worldagent.GetWorldAgent, 1)

// server can also be declared as type interface
var server testserver.IExtendedServer = testserver.New(m, 1)

if len(server.GetAgents()) != 2 {
t.Error("Agents not properly instantiated")
}

for _, agent := range server.GetAgents() {
if agent.GetID() == uuid.Nil {
t.Error("Agent types not correctly instantiated")
}
}

server.Start()
}

func TestServerMessagePassing(t *testing.T) {
m := make([]server.AgentGeneratorCountPair[baseExtendedAgent.IExtendedAgent], 5)

m[0] = server.MakeAgentGeneratorCountPair[baseExtendedAgent.IExtendedAgent](helloagent.GetHelloAgent, 1)
m[1] = server.MakeAgentGeneratorCountPair[baseExtendedAgent.IExtendedAgent](worldagent.GetWorldAgent, 1)

floors := 3
ts := testserver.New(m, floors)

agents := ts.GetAgents()

a1 := agents[0]
a2 := agents[1]

messages := a1.GetAllMessages(agents)

if len(messages) > 1 {
t.Error("Incorrect number of messages created")
}

messages[0].InvokeMessageHandler(a2)
}
Loading

0 comments on commit e34922f

Please sign in to comment.