fix: mark return logic

setting marks for all levels between current speaker and next speker (on
conversation level raise)

and for 'count from' - check higher levels for a mark for potential use
so that 'extend' raised to 'meta' would still count 'next topic' as
going from previously 'extending' person

now going down by many levels - starts from marked person due to 'count from' logic
that uses marks from higher level if current level doesn't have a mark
but also going down by 1 step keeps the marks until we return to initially diverged
conversation layer
This commit is contained in:
efim 2023-11-28 06:29:07 +00:00
parent 60f04cf044
commit de8a661952
2 changed files with 30 additions and 52 deletions

View File

@ -55,7 +55,7 @@ func (r *Room) RaiseHand(p PersonId, gesture HandGesture) Room {
// - 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)
log.Printf("about to release hand of %d in %+v", p, r)
// keeping hand in room until end of funcion in case we'll need it to determine next speaker
defer delete(r.ParticipantHands, p)
@ -85,8 +85,11 @@ func (r *Room) ReleaseHand(p PersonId) {
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())
for gesture := HandGesture(0); gesture < nextSpeakerGesture; gesture++ {
log.Printf("we do have nextSpeaker of priority %s higher than current %s. setting marks between them",
nextSpeakerGesture.String(),
currentSpeakerGesture.String())
for gesture := currentSpeakerGesture; gesture < nextSpeakerGesture; gesture++ {
log.Printf(">>>>> iterating in setting gesture for %s. marks %+v", gesture.String(), r)
_, alreadySet := r.Marks[gesture]
if !alreadySet {
r.Marks[gesture] = p
@ -94,7 +97,7 @@ func (r *Room) ReleaseHand(p PersonId) {
}
}
// also we need to remove marks from top to current speaker level
// also we need to remove marks from top to new current speaker level
for _, gesture := range GesturesHighToLow {
if gesture < nextSpeakerGesture {
break
@ -143,11 +146,15 @@ func (r *Room) NextSpeakerIndex() (nextSpeakerIndex int, found bool, countedFrom
log.Printf("> cur speaker gesture %s and found %t", currentSpeakerGesture.String(), currentSpeakerFound)
return -1, false, -1
}
startIndex := slices.Index(r.Paricipants, r.CurrentSpeaker)
gestureIteration:
for _, gesture := range GesturesHighToLow {
log.Printf("searching for gesture %s", gesture.String())
startIndex := r.gestureSearchStartIndex(gesture, currentSpeakerGesture)
levelMark, levelHasMark := r.Marks[gesture]
if levelHasMark {
startIndex = slices.Index(r.Paricipants, levelMark)
}
participantsCount := len(r.Paricipants)
inGestureParticipantIteration:
for i := 1; i <= participantsCount; i++ {
@ -173,39 +180,6 @@ gestureIteration:
return
}
// find place to start - separate function
// current speaker level, searched gesture level, room marks
// if search level >= current speaker start from speaker
// if search level < current speaekr look for mark, start from mark of that level,
//
// if no mark - from speaker
func (r *Room) gestureSearchStartIndex(gesture, curSpeakerGesture HandGesture) int {
if r.CurrentSpeaker == PersonId(0) {
// nobody is actully a speaker
return 0
}
var personFromWhichToStartSearch PersonId = r.CurrentSpeaker
// if searched guesture is higher or same as current speaker, start from speaker
if gesture >= curSpeakerGesture {
personFromWhichToStartSearch = r.CurrentSpeaker
}
// if searched gesture is of lower priority from current speaker, check marks to return to, or use speaker level
if gesture < curSpeakerGesture {
gestureMark, found := r.Marks[gesture]
if found {
personFromWhichToStartSearch = gestureMark
}
// if no mark found - count from the speaker
}
log.Printf("> selecting person from which to start. cur speaker %d with gesture %s, for gestrue %s, got person %d",
r.CurrentSpeaker, curSpeakerGesture.String(), gesture.String(), personFromWhichToStartSearch)
indexFromWhichToStart := slices.Index(r.Paricipants, personFromWhichToStartSearch)
return indexFromWhichToStart
}
func (r *Room) Equal(other *Room) bool {
if r == other {
return true

View File

@ -14,7 +14,7 @@ type releaseHandTest struct {
var releaseHandTests = []releaseHandTest{
singleHandActive,
raisingLevelFromExpandToClarifyingQ,
raisingLevelFromExpandToMetaQ,
selectNextHigherLevel,
usingMarkToLoverLevel,
releasingNonSpeakerHand,
@ -28,6 +28,8 @@ func TestRoomReleaseHand(t *testing.T) {
test.room.InitMaps()
test.expected.InitMaps()
if test.room.ReleaseHand(test.releasingParticipantId); !test.room.Equal(&test.expected) {
t.Logf("room state is %+v", test.room)
t.Logf("expected state is %+v", test.expected)
t.Errorf("Test release hand diff: (-want +got)\n%s", pretty.Diff(test.room, test.expected))
}
})
@ -78,9 +80,13 @@ var singleHandActive releaseHandTest = releaseHandTest{
}
// 3 person in room, active does expand, next is probingQ,
// this sets mark for all levels from 0 to expand
var raisingLevelFromExpandToClarifyingQ releaseHandTest = releaseHandTest{
testName: "raisingLevelFromExpandToClarifyingQ",
// this sets mark for all levels between levels
// so going down by many levels - starts from marked person due to 'count from' logic
// that uses marks from higher level if current level doesn't have a mark
// but also going down by 1 step keeps the marks until we return to initially diverged
// conversation layer
var raisingLevelFromExpandToMetaQ releaseHandTest = releaseHandTest{
testName: "raisingLevelFromExpandToMetaQ",
room: Room{
Name: "test",
CurrentSpeaker: person1.Id,
@ -91,7 +97,7 @@ var raisingLevelFromExpandToClarifyingQ releaseHandTest = releaseHandTest{
},
ParticipantHands: map[PersonId]HandGesture{
person1.Id: Expand,
person3.Id: ClarifyingQ,
person3.Id: Meta,
},
},
releasingParticipantId: person1.Id,
@ -104,19 +110,17 @@ var raisingLevelFromExpandToClarifyingQ releaseHandTest = releaseHandTest{
person3.Id,
},
ParticipantHands: map[PersonId]HandGesture{
person3.Id: ClarifyingQ,
person3.Id: Meta,
},
Marks: map[HandGesture]PersonId{
ChangeTopic: person1.Id,
ProbingQ: person1.Id,
Expand: person1.Id,
ClarifyingQ: person1.Id,
},
},
}
// 3 person in room, active does expand, next is probingQ,
// already have Mark for Change Topic (0)
// this sets mark for all levels from 1 to expand
// 3 person in room, active does expand, next is meta,
// this sets mark between level of current speaker and next speaker
var raisingLevelSetMarksWithoutOverridingExisting releaseHandTest = releaseHandTest{
testName: "raisingLevelSetMarksWithoutOverridingExisting",
room: Room{
@ -129,7 +133,7 @@ var raisingLevelSetMarksWithoutOverridingExisting releaseHandTest = releaseHandT
},
ParticipantHands: map[PersonId]HandGesture{
person1.Id: Expand,
person3.Id: ClarifyingQ,
person3.Id: Meta,
},
Marks: map[HandGesture]PersonId{
ChangeTopic: person2.Id,
@ -145,12 +149,12 @@ var raisingLevelSetMarksWithoutOverridingExisting releaseHandTest = releaseHandT
person3.Id,
},
ParticipantHands: map[PersonId]HandGesture{
person3.Id: ClarifyingQ,
person3.Id: Meta,
},
Marks: map[HandGesture]PersonId{
ChangeTopic: person2.Id,
ProbingQ: person1.Id,
Expand: person1.Id,
ClarifyingQ: person1.Id,
},
},
}