Created
February 12, 2016 14:57
-
-
Save sam/a7347ee19b94d0cdb122 to your computer and use it in GitHub Desktop.
Not sure how to create a macro that would allow me to extend a trait and have generated code.
This file contains hidden or 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
// Example actor: | |
class EchoActor extends Actor { | |
def receive = { | |
case message => context.sender ! message | |
} | |
} | |
// I want to be able to write: | |
object EchoActor extends ActorGenerator0 | |
// And for that to be equivilent to: | |
object EchoActor extends { | |
val counter = new AtomicLong(1) | |
def apply()(implicit factory: ActorRefFactory): ActorRef = | |
factory.actorOf(Props(new EchoActor(), name = "echo-%d".format(counter.getAndIncrement))) | |
} | |
// So that I can: | |
val echo = EchoActor() | |
// The real point being Actors with constructor arguements: | |
class ArgumentativeActor(prefix: String) extends Actor { | |
def receive = { | |
case message => context.sender ! "%s: %s!".format(prefix, message) | |
} | |
} | |
object ArgumentativeActor extends ActorGenerator1 | |
// And be able to: | |
val argumentative = ArgumentativeActor("NO") | |
// And it be type-safe, because companionClass is used, and it's constructor arguments used to build: | |
// def apply(prefix: String)(implicit factory: ActorRefFactory): ActorRef = | |
// factory.actorOf(Props(new ArgumentativeActor(prefix), name = "argumentative-%d".format(counter.getAndIncrement)) | |
// Macro: | |
object ActorGenerator { | |
implicit def generatorOf[T <: Actor]: Class[ActorGenerator0[T]] = macro generatorOfImpl[T] | |
def generatorOfImpl[T <: Actor : c.WeakTypeTag](c: Context): c.Expr[Class[ActorGenerator0[T]]] = { | |
import c.universe._ | |
val tpe = weakTypeOf[T] | |
val name = tpe.typeSymbol.name.toString | |
c.Expr[Class[ActorGenerator0[T]]] { q""" | |
abstract class ActorGenerator0[$tpe] { | |
import akka.actor._ | |
def name = "%s-%d".format($name, counter.getAndIncrement()) | |
def props() = Props(new $tpe()) | |
def apply()(implicit factory: ActorRefFactory): ActorRef = factory.actorOf(props, name) | |
} | |
""" } | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment