Katrix / AckCord

A Discord library for Scala using Akka
https://ackcord.katsstuff.net/
MIT License
114 stars 15 forks source link

[Suggestion?] A Higher-leveled /modular command framework for AckCord #14

Closed vatsman closed 4 years ago

vatsman commented 5 years ago

Other Discord libraries feature command frameworks that provide utilities that abstract over implementation details and/or boilerplate (usually using a decorator, annotation or some kind of off-handing mechanism) for example: [discord.py's commands extension] (https://discordpy.readthedocs.io/en/rewrite/ext/commands/commands.html) which provides an easier and cleaner interface with the library.

In AckCord, The ping command is in itself quite verbose.

def registerRawCommand[F[_] : Monad : Streamable](client: DiscordClient[F], commands: CommandsHelper[F]): Unit = {
  commands.onRawCmd {
    client.withCache[SourceRequest, RawCmd[F]] { implicit c => {
      case RawCmd(message, Prefix, "echo", args, _) =>
        import client.sourceRequesterRunner._
        for {
          channel <- liftOptionT(message.tGuildChannel[F])
          _ <- run(channel.sendMessage(s"ECHO: ${args.mkString(" ")}"))
        } yield ()
      case _ => client.sourceRequesterRunner.unit
    }
    }
  }
}

where-as using something such as an annotation macro (to avoid the using runtime-reflection)

Katrix commented 5 years ago

I've been planning some in general higher level API on top of AckCord, but that's some way into the future.

As for how commands will look, not sure. Probably won't go with annotation macros though because they play horrible with IntelliJ, and I have no idea how long they will stay alive.

In the meantime though, there's always the slightly less verbose non raw commands.

client.registerCmd[NotUsed, Id](
  prefix = GeneralCommands,
  aliases = Seq("ping"),
  filters = Seq(CmdFilter.NonBot, CmdFilter.InGuild),
  description = Some(CmdDescription("Ping", "Check if the bot is alive"))
) { _ =>
  println(s"Received ping command}")
}

Another option if you only care about the in memory cache is to not care about the F type at all, just hardcode it as Id in most places.

If I did add some sort of annotation macro, it would probably just be syntactic sugar for the above.

Katrix commented 5 years ago

To give some update on the situation here. With 0.13 comes a new experimental commands API completely detached from the previous API.

You can see the equivalent of a ping command here https://github.com/Katrix/AckCord/blob/master/exampleCore/src/main/scala/ackcord/examplecore/NewCommandsController.scala#L15

Do note that command registration is not yet as clean, but I got some plans for that too.

Katrix commented 4 years ago

New commands API is now the default. Old API is being phased out