Last active
August 29, 2015 13:57
-
-
Save RainWarrior/9516577 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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