package ecs type SystemMessageType struct { Name string } type SystemMessage struct { MessageType SystemMessageType Originator System MessageContent map[string]string } // SystemMessageQueue is a super simple way of messaging between systems. Essentially, it is nothing more than a list of // messages. Each message has a type, and an originator. Each system can "subscribe" to a type of message, which // basically just means that it will check the queue for any messages of that type before it does anything else. // Messages can contain a map of information, which each system that creates messages of that type, and those that // subscribe to it should know how to handle any information contained in the message. Ideally, the message queue will // be cleared out occasionally, either by the subscribing systems, or the game loop. Pretty simple for now, but should // solve a subset of problems nicely. type SystemMessageQueue struct { Messages map[System][]SystemMessage Subscriptions map[System][]SystemMessageType } func InitializeSystemMessageQueue() *SystemMessageQueue { smq := SystemMessageQueue{} smq.Messages = make(map[System][]SystemMessage) smq.Subscriptions = make(map[System][]SystemMessageType) return &smq } // BroadcastMessage appends a system message onto the games SystemMessageQueue, allowing it to consumed by a service // subscribes to the MessageType. func (smq *SystemMessageQueue) BroadcastMessage(messageType SystemMessageType, messageContent map[string]string, originator System) { newMessage := SystemMessage{MessageType: messageType, MessageContent: messageContent, Originator: originator} // Find all subscriptions to this message type, and add this message to the subscribers message queue for subscribedSystem, typeList := range smq.Subscriptions { if MessageTypeInSlice(messageType, typeList) { smq.Messages[subscribedSystem] = append(smq.Messages[subscribedSystem], newMessage) } } } // GetSubscribedMessages returns a list of SystemMessages that have messageType. Can return an empty list func (smq *SystemMessageQueue) GetSubscribedMessages(system System) []SystemMessage { messages := []SystemMessage{} for _, message := range smq.Messages[system] { messages = append(messages, message) } return messages } // DeleteMessages deletes a processed message from the queue (for example, if the event has been processed) func (smq *SystemMessageQueue) DeleteMessages(messageName string, system System) { modifiedQueue := smq.Messages[system] for index, message := range smq.Messages[system] { if message.MessageType.Name == messageName { modifiedQueue[index] = modifiedQueue[len(modifiedQueue)-1] modifiedQueue = modifiedQueue[:len(modifiedQueue)-1] } } smq.Messages[system] = modifiedQueue } //MessageTypeInSlice will return true if the MessageType provided is present in the slice provided, false otherwise func MessageTypeInSlice(a SystemMessageType, list []SystemMessageType) bool { for _, b := range list { if b == a { return true } } return false } //MessageTypeInSliceOfMessages will return true if the MessageType provided is present in the slice provided, false otherwise func MessageTypeInSliceOfMessages(a SystemMessageType, list []SystemMessage) bool { for _, b := range list { if b.MessageType == a { return true } } return false }