feat: function to get room next speaker index

This commit is contained in:
efim 2023-11-21 18:57:03 +00:00
parent a10e3433a4
commit 183df0959c
1 changed files with 84 additions and 47 deletions

View File

@ -46,40 +46,100 @@ func (r *Room) RaiseHand(p PersonId, gesture HandGesture) Room {
return *r
}
// and how would i organize?
// i should have map[HandGesture]ParticipantId as mark. for 'from where to go clockwise if returning a level lover'
// now i want methods that for some person raise some hand, so i guess it adds what? to map[ParticipantId]HandGesture
// i suppose methods should be on a room, in a session i'd have ParticipantId to pass in, and would load room
// and i want all parts of room in same struct, because i'd want to subscribe to changes to all of them
// i suppose raising a hand could be just in place adding PersonId->HandGesture,
// but releasing hand should have additional logic
// releasing the hand - removing the hand gesture currently being held by p PersonId
// if p is not current speaker: just removing the signal is ok
// when p is current speaker:
// - we should find next speaker
// - assign room.CurrentSpeaker to next speaker or to PersonId(0) to indicate that noone is speaking
// - if next speaker has gesture of higher priority - set Mark to current speaker for their gesture level
func (r *Room) ReleaseHand(p PersonId) {
// releasing a hand of a current speaker should result in selection of a new speaker
log.Printf("about to release hand of %d in %s", p, r.Name)
// keeping hand in room until end of funcion in case we'll need it to determine next speaker
defer delete(r.ParticipantHands, p)
// first remove hand of the requested person
currentSpeakerGesture, currentSpeakerHandFound := r.ParticipantHands[p]
if !currentSpeakerHandFound {
handReleaseGesture, handReleaserFound := r.ParticipantHands[p]
if !handReleaserFound {
return
}
delete(r.ParticipantHands, p)
// if not a current speaker, no complicated logic required to release a hand
if r.CurrentSpeaker != p {
return
}
// if a current speaker raises their hand
// - in addition to removing the hand, we need to find next speaker
nextSpeakerIndex, nextSpeakerFound, _ := r.NextSpeakerIndex()
if !nextSpeakerFound {
log.Printf("there is not next speaker, that's ok")
r.CurrentSpeaker = PersonId(0)
} else {
// searching for the next speaker
currentSpeakerGesture := handReleaseGesture
nextSpeakerId := r.Paricipants[nextSpeakerIndex]
nextSpeakerGesture := r.ParticipantHands[nextSpeakerId]
log.Printf("found next speaker %+v", nextSpeakerId)
if nextSpeakerGesture > currentSpeakerGesture {
// raising the level of the speaker, need to save mark
log.Printf("we do have nextSpeaker of priority %s higher than current %s", nextSpeakerGesture.String(), currentSpeakerGesture.String())
r.Marks[currentSpeakerGesture] = p
}
// also we need to remove marks from top to current speaker level
for _, gesture := range GesturesHighToLow {
if gesture < nextSpeakerGesture {
break
}
delete(r.Marks, gesture)
}
r.CurrentSpeaker = nextSpeakerId
}
}
// fully remove p PersonId from participants
func (r *Room) PersonToStandUpFromTable(p PersonId) {
personGesture, found := r.ParticipantHands[p]
if found {
r.ReleaseHand(p)
if r.Marks[personGesture] == p {
// the leaving person is marked
// TODO get better logic, maybe assign mark to a neighbor
delete(r.Marks, personGesture)
}
}
if slices.Contains(r.Paricipants, p) {
updated := slices.DeleteFunc(r.Paricipants, func(sittingPerson PersonId) bool {
return sittingPerson == p
})
r.Paricipants = updated
}
}
// find index of next speaker
// for the room with current speaker and their gesture present
// also returning index from which the person was counted:
// - if the gesture of next speaker is of same of higher priority
// should be counted from current speaker
// - if the gesture is of lover priority and there is no mark
// should be counted from current speaker
// - if the gesture is of lover priority and there is a mark for the gesture level
// should be counted from the mark
func (r *Room) NextSpeakerIndex() (nextSpeakerIndex int, found bool, countedFromIndex int) {
// if a current speaker - after removing the hand, we need to find next speaker
// from highest hand gesture to lowest, until one is found
gestures := [...]HandGesture{Meta, ClarifyingQ, Expand, ProbingQ, ChangeTopic}
var nextSpeakerId PersonId
var nextSpeakerFound bool
currentSpeakerGesture, currentSpeakerFound := r.ParticipantHands[r.CurrentSpeaker]
if !currentSpeakerFound {
log.Printf("> cur speaker gesture %s and found %t", currentSpeakerGesture.String(), currentSpeakerFound)
return -1, false, -1
}
gestureIteration:
for _, gesture := range gestures {
for _, gesture := range GesturesHighToLow {
log.Printf("searching for gesture %s", gesture.String())
startIndex := r.gestureSearchStartIndex(gesture, currentSpeakerGesture)
participantsCount := len(r.Paricipants)
@ -88,43 +148,18 @@ gestureIteration:
checkPerson := r.Paricipants[checkIndex]
checkGesture, isFound := r.ParticipantHands[checkPerson]
if isFound && checkGesture == gesture {
nextSpeakerId, nextSpeakerFound = checkPerson, true
nextSpeakerIndex = slices.Index(r.Paricipants, checkPerson)
countedFromIndex = startIndex
found = true
break gestureIteration
}
}
}
if !nextSpeakerFound {
if !found {
log.Printf("there is not next speaker, that's ok")
}
nextSpeakerGesture := r.ParticipantHands[nextSpeakerId]
log.Printf("found next speaker %+v", nextSpeakerId)
if nextSpeakerGesture > currentSpeakerGesture {
// raising the level of the speaker, need to save mark
log.Printf("we do have nextSpeaker of priority %s higher than current %s", nextSpeakerGesture.String(), currentSpeakerGesture.String())
r.Marks[currentSpeakerGesture] = p
}
// also we need to remove marks from top to current speaker level
for _, gesture := range gestures {
if gesture < nextSpeakerGesture {
break
}
delete(r.Marks, gesture)
}
r.CurrentSpeaker = nextSpeakerId
}
func (r *Room) PersonToStandUpFromTable(p PersonId) {
r.ReleaseHand(p)
if slices.Contains(r.Paricipants, p) {
updated := slices.DeleteFunc(r.Paricipants, func(sittingPerson PersonId) bool {
return sittingPerson == p
})
r.Paricipants = updated
}
return
}
// find place to start - separate function
@ -189,6 +224,8 @@ const (
Meta
)
var GesturesHighToLow = [...]HandGesture{Meta, ClarifyingQ, Expand, ProbingQ, ChangeTopic}
func GestureFromInt(num int) (HandGesture, bool) {
if num >= int(ChangeTopic) && num <= int(Meta) {
return HandGesture(num), true