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,57 +46,39 @@ func (r *Room) RaiseHand(p PersonId, gesture HandGesture) Room {
return *r return *r
} }
// and how would i organize? // releasing the hand - removing the hand gesture currently being held by p PersonId
// i should have map[HandGesture]ParticipantId as mark. for 'from where to go clockwise if returning a level lover' // if p is not current speaker: just removing the signal is ok
// now i want methods that for some person raise some hand, so i guess it adds what? to map[ParticipantId]HandGesture // when p is current speaker:
// i suppose methods should be on a room, in a session i'd have ParticipantId to pass in, and would load room // - we should find next speaker
// and i want all parts of room in same struct, because i'd want to subscribe to changes to all of them // - 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
// i suppose raising a hand could be just in place adding PersonId->HandGesture,
// but releasing hand should have additional logic
func (r *Room) ReleaseHand(p PersonId) { func (r *Room) ReleaseHand(p PersonId) {
// releasing a hand of a current speaker should result in selection of a new speaker // 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) 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 handReleaseGesture, handReleaserFound := r.ParticipantHands[p]
currentSpeakerGesture, currentSpeakerHandFound := r.ParticipantHands[p] if !handReleaserFound {
if !currentSpeakerHandFound {
return return
} }
delete(r.ParticipantHands, p)
// if not a current speaker, no complicated logic required to release a hand // if not a current speaker, no complicated logic required to release a hand
if r.CurrentSpeaker != p { if r.CurrentSpeaker != p {
return return
} }
// if a current speaker - after removing the hand, we need to find next speaker // if a current speaker raises their hand
// from highest hand gesture to lowest, until one is found // - in addition to removing the hand, we need to find next speaker
gestures := [...]HandGesture{Meta, ClarifyingQ, Expand, ProbingQ, ChangeTopic} nextSpeakerIndex, nextSpeakerFound, _ := r.NextSpeakerIndex()
var nextSpeakerId PersonId
var nextSpeakerFound bool
gestureIteration:
for _, gesture := range gestures {
log.Printf("searching for gesture %s", gesture.String())
startIndex := r.gestureSearchStartIndex(gesture, currentSpeakerGesture)
participantsCount := len(r.Paricipants)
for i := 1; i < participantsCount; i++ {
checkIndex := (startIndex + i) % participantsCount
checkPerson := r.Paricipants[checkIndex]
checkGesture, isFound := r.ParticipantHands[checkPerson]
if isFound && checkGesture == gesture {
nextSpeakerId, nextSpeakerFound = checkPerson, true
break gestureIteration
}
}
}
if !nextSpeakerFound { if !nextSpeakerFound {
log.Printf("there is not next speaker, that's ok") 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] nextSpeakerGesture := r.ParticipantHands[nextSpeakerId]
log.Printf("found next speaker %+v", nextSpeakerId) log.Printf("found next speaker %+v", nextSpeakerId)
@ -107,7 +89,7 @@ gestureIteration:
} }
// also we need to remove marks from top to current speaker level // also we need to remove marks from top to current speaker level
for _, gesture := range gestures { for _, gesture := range GesturesHighToLow {
if gesture < nextSpeakerGesture { if gesture < nextSpeakerGesture {
break break
} }
@ -116,9 +98,19 @@ gestureIteration:
r.CurrentSpeaker = nextSpeakerId r.CurrentSpeaker = nextSpeakerId
} }
}
// fully remove p PersonId from participants
func (r *Room) PersonToStandUpFromTable(p PersonId) { func (r *Room) PersonToStandUpFromTable(p PersonId) {
personGesture, found := r.ParticipantHands[p]
if found {
r.ReleaseHand(p) 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) { if slices.Contains(r.Paricipants, p) {
updated := slices.DeleteFunc(r.Paricipants, func(sittingPerson PersonId) bool { updated := slices.DeleteFunc(r.Paricipants, func(sittingPerson PersonId) bool {
return sittingPerson == p return sittingPerson == p
@ -127,6 +119,49 @@ func (r *Room) PersonToStandUpFromTable(p PersonId) {
} }
} }
// 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
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 GesturesHighToLow {
log.Printf("searching for gesture %s", gesture.String())
startIndex := r.gestureSearchStartIndex(gesture, currentSpeakerGesture)
participantsCount := len(r.Paricipants)
for i := 1; i < participantsCount; i++ {
checkIndex := (startIndex + i) % participantsCount
checkPerson := r.Paricipants[checkIndex]
checkGesture, isFound := r.ParticipantHands[checkPerson]
if isFound && checkGesture == gesture {
nextSpeakerIndex = slices.Index(r.Paricipants, checkPerson)
countedFromIndex = startIndex
found = true
break gestureIteration
}
}
}
if !found {
log.Printf("there is not next speaker, that's ok")
}
return
}
// find place to start - separate function // find place to start - separate function
// current speaker level, searched gesture level, room marks // current speaker level, searched gesture level, room marks
// if search level >= current speaker start from speaker // if search level >= current speaker start from speaker
@ -189,6 +224,8 @@ const (
Meta Meta
) )
var GesturesHighToLow = [...]HandGesture{Meta, ClarifyingQ, Expand, ProbingQ, ChangeTopic}
func GestureFromInt(num int) (HandGesture, bool) { func GestureFromInt(num int) (HandGesture, bool) {
if num >= int(ChangeTopic) && num <= int(Meta) { if num >= int(ChangeTopic) && num <= int(Meta) {
return HandGesture(num), true return HandGesture(num), true