Skip to content

Instantly share code, notes, and snippets.

@probablytom
Last active July 18, 2018 16:53
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save probablytom/7f16c5c6ba625756a5d5e1daa1d2f31f to your computer and use it in GitHub Desktop.
Save probablytom/7f16c5c6ba625756a5d5e1daa1d2f31f to your computer and use it in GitHub Desktop.
Weird incrementing structs
package SelfIncrementingStruct
import "SelfManagingStructs/TomTypes"
var (
runAlready = false
CollectionSize = 5
usageLimit = 3
SMSCollection = make(chan TomTypes.SelfManagingStruct, CollectionSize)
)
// Initialise a new struct properly, with the StructIncrementer as its "manager"
func constructNewSMStruct() TomTypes.SelfManagingStruct {
return TomTypes.SelfManagingStruct{
Manager: StructIncrementer,
Counter: 0,
Limit: usageLimit,
}
}
// The function that'll increment values in our struct.
func StructIncrementer (sms TomTypes.SelfManagingStruct) { // NOTE: this is a TomTypes.ReturnManager
sms.Counter++
// Refresh our structs if they hit a usage limit!
if sms.Counter == sms.Limit {
sms = constructNewSMStruct()
}
// Pop it back on the stack.
SMSCollection <- sms
}
// Get a self-incrementing struct from our collection of structs.
func GetSMStruct() TomTypes.SelfManagingStruct {
// If we haven't ever populated the channel before, do that.
if !runAlready {
var c int
for c = 0; c < CollectionSize; c++ {
SMSCollection <- constructNewSMStruct()
}
runAlready = true
}
// Just take something from the channel!
return <-SMSCollection
}
package main
import (
"SelfManagingStructs/SelfIncrementingStruct"
"SelfManagingStructs/TomTypes"
"fmt"
"time"
)
func main() {
// Loop through our struct and print the counter value, but just increment them to 1.
var incStruct TomTypes.SelfManagingStruct
var i int
for i = 0; i < 5; i++ {
incStruct = SelfIncrementingStruct.GetSMStruct()
fmt.Println(incStruct.Counter)
incStruct.ManageSelf()
time.Sleep(500 * time.Millisecond)
}
// Change the behaviour so that the structs are still put onto the channel encapsulated in the old manager, but don't let the counter increment.
for i = 0; i < 5; i++ {
incStruct = SelfIncrementingStruct.GetSMStruct()
incStruct.Manager = BehaviourChanger(incStruct.Manager)
incStruct.ManageSelf()
}
// Infinitely loop as we would usually, printing the values.
for {
incStruct = SelfIncrementingStruct.GetSMStruct()
fmt.Println(incStruct.Counter)
incStruct.ManageSelf()
time.Sleep(500 * time.Millisecond)
}
}
func BehaviourChanger(oldManager TomTypes.ReturnManager) TomTypes.ReturnManager {
return func(managingStruct TomTypes.SelfManagingStruct) {
managingStruct.Counter--
oldManager(managingStruct)
}
}
package TomTypes
type ReturnManager func(SelfManagingStruct)
type SelfManagingStruct struct {
Manager ReturnManager
Counter int
Limit int
}
func (sms SelfManagingStruct) ManageSelf() {
sms.Manager(sms)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment