Skip to content

Instantly share code, notes, and snippets.

@RainWarrior
Last active August 29, 2015 13:57
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save RainWarrior/9516577 to your computer and use it in GitHub Desktop.
Save RainWarrior/9516577 to your computer and use it in GitHub Desktop.
abstract class GatePart[P <: GatePart[P, L], L <: GateLogic[P, L]] { this: P =>
def getLogic: L
def onChange() {
getLogic.onChange(this)
}
}
abstract class GateLogic[P <: GatePart[P, L], L <: GateLogic[P, L]] {
def onChange(gate: P) {
}
}
class GatePart1 extends GatePart[GatePart1, GateLogic2] {
override def getLogic: GateLogic2 = null
}
class GateLogic1[P <: GatePart[P, L], L <: GateLogic[P, L]] extends GateLogic[P, L]
class GateLogic2 extends GateLogic1[GatePart1, GateLogic2]
// generic ones, with least amount of constraints
trait PartLogic[PL <: PartLogic[PL]] { this: PL =>
type P <: GatePart[PL]
type L <: GateLogic[PL]
}
trait GatePart[PL <: PartLogic[PL]] { this: PL#P =>
type P = PL#P
type L = PL#L
def getLogic: L
def onChange() {
getLogic.onChange(this)
}
}
trait GateLogic[PL <: PartLogic[PL]] { this: PL#L =>
type P = PL#P
type L = PL#L
def onChange(gate: P) {
println("onChange")
}
}
// next tier down, GatePart1 requires at least GateLogic1 for call of onChange2
trait PartLogic1[PL <: PartLogic1[PL]] extends PartLogic[PL] { this: PL =>
type P <: GatePart1[PL]
type L <: GateLogic1[PL]
}
trait GatePart1[PL <: PartLogic1[PL]] extends GatePart[PL] { this: PL#P =>
def onChange2() {
getLogic.onChange2(this)
}
}
trait GateLogic1[PL <: PartLogic[PL]] extends GateLogic[PL] { this: PL#L =>
def onChange2(gate: P) {
println("onChange2")
}
}
// bottom, extension down still works
class PartLogic2 extends PartLogic1[PartLogic2] {
type P = GatePart2
type L = GateLogic2
}
class GatePart2 extends GatePart1[PartLogic2] {
override def getLogic = new GateLogic2
}
class GateLogic2 extends GateLogic1[PartLogic2]
object Main {
def main(args: Array[String]) {
val part = new GatePart2
part.onChange()
part.onChange2()
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment