Skip to content

Commit

Permalink
Handle recursive controlling actions in APL
Browse files Browse the repository at this point in the history
  • Loading branch information
jimmyt857 committed Nov 1, 2023
1 parent 0c71440 commit 0bb7730
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 11 deletions.
19 changes: 15 additions & 4 deletions sim/core/apl.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ type APLRotation struct {
priorityList []*APLAction

// Action currently controlling this rotation (only used for certain actions, such as StrictSequence).
controllingAction APLActionImpl
controllingActions []APLActionImpl

// Value that should evaluate to 'true' if the current channel is to be interrupted.
// Will be nil when there is no active channel.
Expand Down Expand Up @@ -166,7 +166,7 @@ func (rot *APLRotation) allPrepullActions() []*APLAction {
}

func (rot *APLRotation) reset(sim *Simulation) {
rot.controllingAction = nil
rot.controllingActions = nil
rot.inLoop = false
rot.interruptChannelIf = nil
rot.allowChannelRecastOnInterrupt = false
Expand Down Expand Up @@ -219,8 +219,8 @@ func (apl *APLRotation) DoNextAction(sim *Simulation) {
}

func (apl *APLRotation) getNextAction(sim *Simulation) *APLAction {
if apl.controllingAction != nil {
return apl.controllingAction.GetNextAction(sim)
if len(apl.controllingActions) != 0 {
return apl.controllingActions[len(apl.controllingActions)-1].GetNextAction(sim)
}

for _, action := range apl.priorityList {
Expand All @@ -232,6 +232,17 @@ func (apl *APLRotation) getNextAction(sim *Simulation) *APLAction {
return nil
}

func (apl *APLRotation) pushControllingAction(ca APLActionImpl) {
apl.controllingActions = append(apl.controllingActions, ca)
}

func (apl *APLRotation) popControllingAction(ca APLActionImpl) {
if len(apl.controllingActions) == 0 || apl.controllingActions[len(apl.controllingActions)-1] != ca {
panic("Wrong APL controllingAction in pop()")
}
apl.controllingActions = apl.controllingActions[:len(apl.controllingActions)-1]
}

func (apl *APLRotation) shouldInterruptChannel(sim *Simulation) bool {
channeledDot := apl.unit.ChanneledDot

Expand Down
6 changes: 3 additions & 3 deletions sim/core/apl_actions_sequences.go
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ func (action *APLActionStrictSequence) IsReady(sim *Simulation) bool {
return true
}
func (action *APLActionStrictSequence) Execute(sim *Simulation) {
action.unit.Rotation.controllingAction = action
action.unit.Rotation.pushControllingAction(action)
}
func (action *APLActionStrictSequence) GetNextAction(sim *Simulation) *APLAction {
if action.subactions[action.curIdx].IsReady(sim) {
Expand All @@ -145,15 +145,15 @@ func (action *APLActionStrictSequence) GetNextAction(sim *Simulation) *APLAction
action.curIdx++
if action.curIdx == len(action.subactions) {
action.curIdx = 0
action.unit.Rotation.controllingAction = nil
action.unit.Rotation.popControllingAction(action)
}

return nextAction
} else if action.unit.GCD.IsReady(sim) {
// If the GCD is ready when the next subaction isn't, it means the sequence is bad
// so reset and exit the sequence.
action.curIdx = 0
action.unit.Rotation.controllingAction = nil
action.unit.Rotation.popControllingAction(action)
return action.unit.Rotation.getNextAction(sim)
} else {
// Return nil to wait for the GCD to become ready.
Expand Down
8 changes: 4 additions & 4 deletions sim/core/apl_actions_timing.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ func (action *APLActionWait) IsReady(sim *Simulation) bool {
}

func (action *APLActionWait) Execute(sim *Simulation) {
action.unit.Rotation.controllingAction = action
action.unit.Rotation.pushControllingAction(action)
action.curWaitTime = sim.CurrentTime + action.duration.GetDuration(sim)

pa := &PendingAction{
Expand All @@ -49,7 +49,7 @@ func (action *APLActionWait) Execute(sim *Simulation) {

func (action *APLActionWait) GetNextAction(sim *Simulation) *APLAction {
if sim.CurrentTime >= action.curWaitTime {
action.unit.Rotation.controllingAction = nil
action.unit.Rotation.popControllingAction(action)
return action.unit.Rotation.getNextAction(sim)
} else {
return nil
Expand Down Expand Up @@ -86,12 +86,12 @@ func (action *APLActionWaitUntil) IsReady(sim *Simulation) bool {
}

func (action *APLActionWaitUntil) Execute(sim *Simulation) {
action.unit.Rotation.controllingAction = action
action.unit.Rotation.pushControllingAction(action)
}

func (action *APLActionWaitUntil) GetNextAction(sim *Simulation) *APLAction {
if action.condition.GetBool(sim) {
action.unit.Rotation.controllingAction = nil
action.unit.Rotation.popControllingAction(action)
return action.unit.Rotation.getNextAction(sim)
} else {
return nil
Expand Down

0 comments on commit 0bb7730

Please sign in to comment.