Skip to content

Commit

Permalink
Added support for external transitions (could use a full test).
Browse files Browse the repository at this point in the history
  • Loading branch information
clnhlzmn committed Mar 27, 2021
1 parent d25b6be commit 9b59057
Show file tree
Hide file tree
Showing 5 changed files with 55 additions and 36 deletions.
10 changes: 5 additions & 5 deletions makina-compiler/src/xyz/colinholzman/makina/CodeGenerator.kt
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ class CodeGenerator(val machine: Machine,
private fun generateExitActions(handler: Handler.Event, sourceState: State, activeLeafState: State, output: PrintWriter) {
if (handler.target != null) output.apply {
val target = handler.getTargetState(sourceState, machine)
val transition = Transition(activeLeafState, target)
val transition = Transition(activeLeafState, sourceState, target)
val exitSet = transition.getExitSet()
for (stateToExit in exitSet) {
for (exit in stateToExit.handlers.filterIsInstance<Handler.Exit>()) {
Expand All @@ -70,10 +70,10 @@ class CodeGenerator(val machine: Machine,
private fun generateEntryActions(handler: Handler.Event, sourceState: State, activeLeafState: State, output: PrintWriter) {
if (handler.target != null) output.apply {
val target = handler.getTargetState(sourceState, machine)
val transition = Transition(activeLeafState, target)
val entrySet = transition.getEntrySet() + target.getDefaultEntrySet()
val leafStateTarget = if (target.isLeafState()) target else target.getDefaultEntrySet().last()
println("\t\t\tself->state = ${machine.id}_${leafStateTarget.getFullyQualifiedIdString()};")
val transition = Transition(activeLeafState, sourceState, target)
val entrySet = transition.getEntrySet()
val targetLeafState = entrySet.last()
println("\t\t\tself->state = ${machine.id}_${targetLeafState.getFullyQualifiedIdString()};")
for (stateToEnter in entrySet) {
for (entry in stateToEnter.handlers.filterIsInstance<Handler.Entry>()) {
println("\t\t\t${entry.action}(self, event);")
Expand Down
8 changes: 2 additions & 6 deletions makina-compiler/src/xyz/colinholzman/makina/State.kt
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,8 @@ class State(val id: String,
return ret
}

fun isDescendantOf(other: State): Boolean {
fun isDescendantOf(other: State?): Boolean {
if (other == null) return true
var current: State? = this
while (current != null) {
if (current.parent == other)
Expand Down Expand Up @@ -172,11 +173,6 @@ class State(val id: String,
}
return null
}

//returns true if all states are descendants of the same ancestor
fun List<State>.areRelated(): Boolean {
return map { it.getStateConfiguration().getParentState() }.toSet().size == 1
}
}

}
29 changes: 20 additions & 9 deletions makina-compiler/src/xyz/colinholzman/makina/Transition.kt
Original file line number Diff line number Diff line change
@@ -1,17 +1,28 @@
package xyz.colinholzman.makina

import xyz.colinholzman.makina.State.Companion.areRelated
import xyz.colinholzman.makina.State.Companion.getLCCA

data class Transition(val source: State, val target: State) {
init {
if (!source.isLeafState())
throw RuntimeException("source must be a leaf state")
}
data class Transition(val activeLeafState: State,
val source: State, val target: State,
val kind: Target.Kind = Target.Kind.DEFAULT) {
fun getEntrySet(): List<State> {
return (listOf(target) + target.getProperAncestors(listOf(source, target).getLCCA())).reversed()
return (listOf(target) + target.getDefaultEntrySet() + target.getProperAncestors(getDomain()))
.sortedBy { it.getDepth() }
}

fun getExitSet(): List<State> {
return listOf(source) + source.getProperAncestors(listOf(source, target).getLCCA())
val domain = getDomain()
return activeLeafState.getStateConfiguration().states
.filter { it.isDescendantOf(domain) }
.sortedBy { it.getDepth() }.reversed()
}

fun getDomain(): State? {
return if (kind == Target.Kind.DEFAULT
&& !source.isLeafState()
&& target.isDescendantOf(source))
source
else
listOf(source, target).getLCCA()
}
}
}
1 change: 1 addition & 0 deletions makina-compiler/test/xyz/colinholzman/makina/StateTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,7 @@ internal class StateTest {
bar.parent = foo
assert(bar.isDescendantOf(foo))
assertFalse(foo.isDescendantOf(bar))
assertTrue(foo.isDescendantOf(null))
}

@Test
Expand Down
43 changes: 27 additions & 16 deletions makina-compiler/test/xyz/colinholzman/makina/TransitionTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import xyz.colinholzman.makina.TestStates.Companion.s1
import xyz.colinholzman.makina.TestStates.Companion.s11
import xyz.colinholzman.makina.TestStates.Companion.s111
import xyz.colinholzman.makina.TestStates.Companion.s12
import xyz.colinholzman.makina.TestStates.Companion.s121
import xyz.colinholzman.makina.TestStates.Companion.s122
import xyz.colinholzman.makina.TestStates.Companion.s2
import xyz.colinholzman.makina.TestStates.Companion.s21
Expand All @@ -15,25 +16,35 @@ internal class TransitionTest {

@Test
fun getEntrySet() {
var transition = Transition(s111, s122)
assertEquals(listOf(s12, s122), transition.getEntrySet())
transition = Transition(s111, s21)
assertEquals(listOf(s2, s21), transition.getEntrySet())
transition = Transition(s111, s111)
assertEquals(listOf(s111), transition.getEntrySet())
transition = Transition(s111, s1)
assertEquals(listOf(s1), transition.getEntrySet())
assertEquals(listOf(s12, s122), Transition(s111, s111, s122).getEntrySet())
assertEquals(listOf(s2, s21), Transition(s111, s111, s21).getEntrySet())
assertEquals(listOf(s111), Transition(s111, s111, s111).getEntrySet())
assertEquals(listOf(s1, s12, s121), Transition(s111, s111, s1).getEntrySet())
assertEquals(listOf(s1, s12, s121), Transition(s111, s1, s1).getEntrySet())
assertEquals(listOf(s2, s21), Transition(s111, s111, s2).getEntrySet())
}

@Test
fun getExitSet() {
var transition = Transition(s111, s122)
assertEquals(listOf(s111, s11), transition.getExitSet())
transition = Transition(s111, s21)
assertEquals(listOf(s111, s11, s1), transition.getExitSet())
transition = Transition(s111, s111)
assertEquals(listOf(s111), transition.getExitSet())
transition = Transition(s111, s1)
assertEquals(listOf(s111, s11, s1), transition.getExitSet())
assertEquals(listOf(s111, s11), Transition(s111, s111, s122).getExitSet())
assertEquals(listOf(s111, s11, s1), Transition(s111, s111, s21).getExitSet())
assertEquals(listOf(s111), Transition(s111, s111, s111).getExitSet())
assertEquals(listOf(s111, s11, s1), Transition(s111, s111, s1).getExitSet())
assertEquals(listOf(s111, s11, s1), Transition(s111, s1, s1).getExitSet())
assertEquals(listOf(s111, s11), Transition(s111, s1, s12).getExitSet())
assertEquals(listOf(s111, s11, s1), Transition(s111, s1, s12, Target.Kind.EXTERNAL).getExitSet())
assertEquals(listOf(s111, s11, s1), Transition(s111, s1, s121, Target.Kind.EXTERNAL).getExitSet())
assertEquals(listOf(s111), Transition(s111, s111, s111, Target.Kind.EXTERNAL).getExitSet())
assertEquals(listOf(s111, s11, s1), Transition(s111, s1, s1, Target.Kind.EXTERNAL).getExitSet())
}

@Test
fun getDomain() {
assertEquals(null, Transition(s111, s1, s2).getDomain())
assertEquals(null, Transition(s111, s11, s21).getDomain())
assertEquals(s1, Transition(s111, s11, s12).getDomain())
assertEquals(s1, Transition(s111, s1, s11).getDomain())
assertEquals(null, Transition(s111, s1, s11, Target.Kind.EXTERNAL).getDomain())
assertEquals(null, Transition(s111, s11, s1).getDomain())
}
}

0 comments on commit 9b59057

Please sign in to comment.