Skip to content

Commit

Permalink
fix: remove cats
Browse files Browse the repository at this point in the history
  • Loading branch information
Lucky3028 committed Jan 14, 2024
1 parent f6e89fb commit 93dc44d
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 130 deletions.
2 changes: 1 addition & 1 deletion build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ val providedDependencies = Seq(
).map(_ % "provided")

val embeddedDependencies =
Seq("com.beachape" %% "enumeratum" % "1.7.0", "org.typelevel" %% "cats-effect" % "3.3.14")
Seq("com.beachape" %% "enumeratum" % "1.7.0",)

val testDependencies = Seq(
"org.scalamock" %% "scalamock" % "5.2.0",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,20 +1,15 @@
package click.seichi.regenerateworld.presenter.runnable

import cats.Monad
import cats.effect.std.Dispatcher
import cats.implicits._
import cats.effect.{Async, IO, Sync}
import click.seichi.regenerateworld.domain.model.{GenerationSchedule, SeedPattern}
import click.seichi.regenerateworld.presenter.GenerationScheduleUseCase
import click.seichi.regenerateworld.presenter.mixin.MixInClock
import click.seichi.regenerateworld.presenter.shared.WorldRegenerator
import click.seichi.regenerateworld.presenter.shared.exception.WorldRegenerationException
import org.bukkit.{Bukkit, ChatColor, World}
import org.bukkit.plugin.java.JavaPlugin
import org.bukkit.scheduler.{BukkitRunnable, BukkitTask}
import org.bukkit.{Bukkit, ChatColor}

import java.time.temporal.ChronoUnit
import scala.concurrent.duration.DurationInt

object RegenerationTask extends MixInClock {
def runAtNextDate(schedule: GenerationSchedule)(implicit instance: JavaPlugin): BukkitTask = {
Expand All @@ -28,138 +23,55 @@ object RegenerationTask extends MixInClock {

def runInstantly(schedule: GenerationSchedule)(
implicit instance: JavaPlugin
): IO[List[Unit]] =
new RegenerationTask(schedule).ooo[IO]()
}

trait OnMinecraftServerThread[F[_]] {

/**
* マインクラフトサーバーが走るスレッド上でアクションを実行する。
*/
def runAction[G[_]: Dispatcher: Sync, A](ga: G[A]): F[A]
}

object OnMinecraftServerThread {
def apply[F[_]](implicit ev: OnMinecraftServerThread[F]): OnMinecraftServerThread[F] = ev
}

class OnBukkitServerThread[F[_]: Monad: Async](implicit plugin: JavaPlugin)
extends OnMinecraftServerThread[F] {
override def runAction[G[_]: Async, A](ga: G[A]): F[A] = {
val checkMainThread = Sync[G].delay {
plugin.getServer.isPrimaryThread
}

for {
immediateResult <- checkMainThread.ifM[Option[A]](ga.map(Some.apply), Monad[G].pure(None))
result <- immediateResult match {
case Some(value) => Monad[F].pure(value)
case None =>
Async[F].async[A] { cb =>
val runnable: Runnable = () => {
val a =
Dispatcher[G].use(dispatcher => Sync[G].delay(dispatcher.unsafeRunSync(ga)))

cb(a.asRight)
}

val task = Bukkit.getScheduler.runTask(plugin, runnable)
Async[F].delay(task.cancel())
}
}
} yield result
}
): Unit =
new RegenerationTask(schedule).run()
}

private class RegenerationTask(private val schedule: GenerationSchedule)(
implicit instance: JavaPlugin
) {
private def aaaa[F[_]: Async](worldName: String): F[Unit] = {
val seedPattern =
if (schedule.seedPattern.seedValueIsRequiredExplicitly) SeedPattern.RandomNewSeed
else schedule.seedPattern

for {
world <- Async[F].delay(Option(Bukkit.getWorld(worldName)))
result <- new OnBukkitServerThread[F]
.runAction(Sync[F].delay(WorldRegenerator.regenBukkitWorld(world, seedPattern, None)))
// result <- Sync[F].delay(WorldRegenerator.regenBukkitWorld(world, seedPattern, None))
} yield {
val logger = instance.getLogger

result match {
case Right(worldName) =>
logger.info(
s"The world (name: $worldName) regeneration schedule (ID: ${schedule.id}) has completed"
)
case Left(e) =>
logger.severe(
s"Error has occurred while regenerating a world with the schedule (ID: ${schedule.id}): ${e.description}"
private def run(): Unit =
for (count <- 10 to 0 by -1) {
count match {
case 1 | 3 | 5 | 10 =>
Bukkit.broadcastMessage(
s"${ChatColor.RED}The regeneration of ${schedule.worlds.mkString(", ")} will be held in $count minute(s)!"
)
}
}
}

def ooo[F[_]: Async](): F[List[Unit]] = {
val countDowns = Set(1, 2, 3, 5, 10)

(10 to 0 by -1).toList.traverse { count =>
for {
_ <-
Async[F]
.delay {
Bukkit.broadcastMessage(
s"${ChatColor.RED}The regeneration of ${schedule.worlds.mkString(", ")} will be held in $count minute(s)!"
)
case 0 =>
val regenResults = for {
worldName <- schedule.worlds
} yield for {
world <- Option(Bukkit.getWorld(worldName))
.toRight(WorldRegenerationException.WorldIsNotFound(worldName))
seedPattern =
if (schedule.seedPattern.seedValueIsRequiredExplicitly) SeedPattern.RandomNewSeed
else schedule.seedPattern
_ = new BukkitRunnable() {
override def run(): Unit =
WorldRegenerator.regenBukkitWorld(Some(world), seedPattern, None)
}.runTask(instance)
} yield worldName

regenResults.foreach(res => {
val logger = instance.getLogger

res match {
case Right(worldName) =>
logger.info(
s"The world (name: $worldName) regeneration schedule (ID: ${schedule.id}) has completed"
)
case Left(e) =>
logger.severe(
s"Error has occurred while regenerating a world with the schedule (ID: ${schedule.id}): ${e.description}"
)
}
.whenA(countDowns.contains(count))
_ <- schedule.worlds.toList.traverse(aaaa(_)).whenA(count == 0)
_ <- Async[F].sleep(1.seconds)
} yield ()
}
}
})

def run(): Unit =
for (count <- 10 to 0 by -1) {
if (count == 0) {
val regenResults = for {
worldName <- schedule.worlds
} yield for {
world <- Option(Bukkit.getWorld(worldName))
.toRight(WorldRegenerationException.WorldIsNotFound(worldName))
seedPattern =
if (schedule.seedPattern.seedValueIsRequiredExplicitly) SeedPattern.RandomNewSeed
else schedule.seedPattern
_ = new BukkitRunnable() {
override def run(): Unit =
WorldRegenerator.regenBukkitWorld(Some(world), seedPattern, None)
// Scheduleの次回日時の設定は1回でいいので、for-yieldの外に置く
new BukkitRunnable {
override def run(): Unit = GenerationScheduleUseCase.finish(schedule.id)
}.runTask(instance)
} yield worldName

regenResults.foreach(res => {
val logger = instance.getLogger

res match {
case Right(worldName) =>
logger.info(
s"The world (name: $worldName) regeneration schedule (ID: ${schedule.id}) has completed"
)
case Left(e) =>
logger.severe(
s"Error has occurred while regenerating a world with the schedule (ID: ${schedule.id}): ${e.description}"
)
}
})

// Scheduleの次回日時の設定は1回でいいので、for-yieldの外に置く
new BukkitRunnable {
override def run(): Unit = GenerationScheduleUseCase.finish(schedule.id)
}.runTask(instance)
} else if (Set(1, 3, 5, 10).contains(count)) {
Bukkit.broadcastMessage(
s"${ChatColor.RED}The regeneration of ${schedule.worlds.mkString(", ")} will be held in $count minute(s)!"
)
case _ =>
}

// TODO: wait 60 secs
Expand Down

0 comments on commit 93dc44d

Please sign in to comment.