diff options
| author | Abdellah El Morabit <nsrddyn@gmail.com> | 2025-11-28 12:29:11 +0100 |
|---|---|---|
| committer | Abdellah El Morabit <nsrddyn@gmail.com> | 2025-11-28 14:05:26 +0100 |
| commit | 4d371f53e80231c83af6afcc20dc5c9390cfeb8c (patch) | |
| tree | 940d6a4e8218039138636dfb08a0b0b737ac31da /src/main | |
| parent | 21806a2c70479cdb5b45c88b6fe6e26dc6901abf (diff) | |
feature: basic implementation of tui & folder and file refactorings for resources and runners
Diffstat (limited to 'src/main')
| -rw-r--r-- | src/main/scala/main/Main.scala | 72 | ||||
| -rw-r--r-- | src/main/scala/main/Ops/Ops.scala | 3 | ||||
| -rw-r--r-- | src/main/scala/main/Ops/Resources.scala | 36 | ||||
| -rw-r--r-- | src/main/scala/main/Tests/Tests.scala | 14 | ||||
| -rw-r--r-- | src/main/scala/main/Tools/Benchmark.scala | 6 | ||||
| -rw-r--r-- | src/main/scala/main/Tools/Runner.scala | 42 | ||||
| -rw-r--r-- | src/main/scala/main/Traits/Workload.scala | 13 | ||||
| -rw-r--r-- | src/main/scala/main/Tui/Tui.scala | 130 |
8 files changed, 229 insertions, 87 deletions
diff --git a/src/main/scala/main/Main.scala b/src/main/scala/main/Main.scala index ebc82f0..4180eda 100644 --- a/src/main/scala/main/Main.scala +++ b/src/main/scala/main/Main.scala @@ -1,10 +1,12 @@ package main -import Ops.* -import Tests.* +import main.Ops.* +import main.Tests.* +import main.Tools.* +import main.Runner.* import oshi._ -import java.time.Instant import zio._ +import main.tui.* /* @@ -16,65 +18,11 @@ import zio._ object Torque extends ZIOAppDefault { - // system resources - val si: SystemInfo = new SystemInfo - val sensors = si.getHardware.getSensors - val cpu = si.getHardware.getProcessor - - // stress operations - val p = new Prime - val cd = new CholeskyDecomposition - - def failSafe: Unit = while (true) do if sensors.getCpuTemperature > 80 then println("overheat") - - def runCholeskyTest: ZIO[Any, Throwable, Unit] = { - - ZIO.attempt { - //TODO: declare a randomized array to pass into the runner - // cd.run(matrix) - }.catchAll { error => Console.printError(s"failed: $error")} - - } - - def runPrimeTest: ZIO[Any, Throwable, Unit] = { - ZIO.attempt { - // p.run(390483094, true) - }.catchAll { error => Console.printError(s"failed: $error")} - } - - def runSequential: ZIO[Any, Throwable, Unit] = { - - Console.printLine("sequential test") *> - runCholeskyTest *> - runPrimeTest - } - - def runParallel: ZIO[Any, Throwable, Unit] = { - - Console.printLine("CholeskyTest") *> - (runCholeskyTest <&> runPrimeTest).unit - } - - def getPlatform: ZIO[Any, Throwable, Unit] = { - ZIO.attempt { - println(si.getHardware) - }.catchAll { error => Console.printError(s"failed :$error")} - } - - def getCpuFrequency: ZIO[Any, Throwable, Unit] = { - ZIO.attempt { - /* - * 227 oshi/hardware/CentralProcessor.java - * method takes long value as delay - * */ - println("load: " + cpu.getSystemCpuLoad(1000) * 1000) - println("logical cores: " + cpu.getLogicalProcessorCount()) - println("cores: " + cpu.getPhysicalProcessorCount()) - println("temperature: " + sensors.getCpuTemperature()) - } - } - def run: ZIO[ZIOAppArgs & Scope, Any, Any] = { - Console.printLine("=== TORQUE STRESS TEST ===") *> runParallel <*> getPlatform <*> getCpuFrequency + Console.printLine("=== TORQUE STRESS TEST ===") + val uix: UserInputExample = new UserInputExample() + uix.execute() + } + } diff --git a/src/main/scala/main/Ops/Ops.scala b/src/main/scala/main/Ops/Ops.scala index 821f39b..214b824 100644 --- a/src/main/scala/main/Ops/Ops.scala +++ b/src/main/scala/main/Ops/Ops.scala @@ -1,7 +1,6 @@ package main.Ops -import main.tools.Benchmark -import main.Traits.* +import main.Tools.* import scala.util.hashing import scala.util.hashing.MurmurHash3 diff --git a/src/main/scala/main/Ops/Resources.scala b/src/main/scala/main/Ops/Resources.scala new file mode 100644 index 0000000..cd9cade --- /dev/null +++ b/src/main/scala/main/Ops/Resources.scala @@ -0,0 +1,36 @@ +package main.Resources + +import main.Ops.* +import main.Tests.* +import main.Tools.* +import oshi._ +import zio._ + +class Resources { + + val si: SystemInfo = new SystemInfo + val sensors = si.getHardware.getSensors + val cpu = si.getHardware.getProcessor + + def failSafe: Unit = while (true) do if sensors.getCpuTemperature > 80 then println("overheat") + + def getPlatform: ZIO[Any, Throwable, Unit] = { + ZIO.attempt { + println(si.getHardware) + }.catchAll { error => Console.printError(s"failed :$error")} + } + + + def getCpuFrequency: ZIO[Any, Throwable, Unit] = { + ZIO.attempt { + /* + * 227 oshi/hardware/CentralProcessor.java + * method takes long value as delay + * */ + // println("load: " + cpu.getSystemCpuLoad(1000) * 1000) + // println("logical cores: " + cpu.getLogicalProcessorCount()) + // println("cores: " + cpu.getPhysicalProcessorCount()) + // println("temperature: " + sensors.getCpuTemperature()) + } + } +} diff --git a/src/main/scala/main/Tests/Tests.scala b/src/main/scala/main/Tests/Tests.scala index 494a5db..93c21a6 100644 --- a/src/main/scala/main/Tests/Tests.scala +++ b/src/main/scala/main/Tests/Tests.scala @@ -1,18 +1,14 @@ package main.Tests -import scala.collection.immutable.ListSet +import main.Ops.* +import main.Tools.* import zio._ -import main.Ops.CholeskyDecomposition - - -class CholeskyDecompositionRunner { +import scala.collection.immutable.ListSet - def test(): Unit = { +class Test { - val cdp: CholeskyDecomposition = new CholeskyDecomposition - val matrix: Vector[Vector[Int]] = Vector(Vector(1,2,3),Vector(1,2,3),Vector(1,2,3)) + def run(): Unit = { - println(cdp.run(matrix)) } } diff --git a/src/main/scala/main/Tools/Benchmark.scala b/src/main/scala/main/Tools/Benchmark.scala index eb1a6d4..04b9861 100644 --- a/src/main/scala/main/Tools/Benchmark.scala +++ b/src/main/scala/main/Tools/Benchmark.scala @@ -1,6 +1,10 @@ -package main.tools +package main.Tools import main.Ops.* +import main.Tests.* +import main.Tools.* +import oshi._ +import java.time.Instant class Benchmark { /* diff --git a/src/main/scala/main/Tools/Runner.scala b/src/main/scala/main/Tools/Runner.scala new file mode 100644 index 0000000..384ec5d --- /dev/null +++ b/src/main/scala/main/Tools/Runner.scala @@ -0,0 +1,42 @@ +package main.Runner + +import main.Ops.* +import main.Tests.* +import main.Tools.* +import oshi._ +import zio._ + +class Runner { + + val p = new Prime + val cd = new CholeskyDecomposition + + + def runCholeskyTest: ZIO[Any, Throwable, Unit] = { + ZIO.attempt { + //TODO: declare a randomized array to pass into the runner + // cd.run(matrix) + }.catchAll { error => Console.printError(s"failed: $error")} + } + + def runPrimeTest: ZIO[Any, Throwable, Unit] = { + ZIO.attempt { + // p.run(390483094, true) + }.catchAll { error => Console.printError(s"failed: $error")} + } + + def runSequential: ZIO[Any, Throwable, Unit] = { + + Console.printLine("sequential test") *> + runCholeskyTest *> + runPrimeTest + } + + def runParallel: ZIO[Any, Throwable, Unit] = { + + Console.printLine("CholeskyTest") *> + (runCholeskyTest <&> runPrimeTest).unit + } + +} + diff --git a/src/main/scala/main/Traits/Workload.scala b/src/main/scala/main/Traits/Workload.scala deleted file mode 100644 index 5fd8527..0000000 --- a/src/main/scala/main/Traits/Workload.scala +++ /dev/null @@ -1,13 +0,0 @@ -package main.Traits - -import zio._ - -enum Status: - case PASS - case FAIL - -trait Workload { - - def name: String - def run: ZIO[Any, Nothing, Unit] -} diff --git a/src/main/scala/main/Tui/Tui.scala b/src/main/scala/main/Tui/Tui.scala new file mode 100644 index 0000000..37b3fbd --- /dev/null +++ b/src/main/scala/main/Tui/Tui.scala @@ -0,0 +1,130 @@ +package main.tui + +import tui._ +import tui.crossterm.{CrosstermJni, KeyCode} +import tui.widgets.{BlockWidget, ParagraphWidget} +import tui.widgets.ListWidget + +class UserInputExample { + sealed trait InputMode + object InputMode { + case object Normal extends InputMode + case object Editing extends InputMode + } + + /// App holds the state of the application + case class App ( + /// Current value of the input box + var input: String = "", + /// Current input mode + var input_mode: InputMode = InputMode.Normal, + /// History of recorded messages + var messages: Array[String] = Array.empty + ) + + def execute(): Unit = withTerminal { (jni, terminal) => + // create app and run it + val app = App() + run_app(terminal, app, jni) + } + + def run_app(terminal: Terminal, app: App, jni: CrosstermJni): Unit = + while (true) { + terminal.draw(f => ui(f, app)) + + jni.read() match { + case key: tui.crossterm.Event.Key => + app.input_mode match { + case InputMode.Normal => + key.keyEvent().code() match { + case c: KeyCode.Char if c.c == 'e' => app.input_mode = InputMode.Editing; + case c: KeyCode.Char if c.c == 'q' => return + case _ => () + } + case InputMode.Editing => + key.keyEvent().code() match { + case _: KeyCode.Enter => + app.messages = app.messages :+ app.input + app.input = "" + case c: KeyCode.Char => app.input = app.input + c.c(); + case _: KeyCode.Backspace => app.input = app.input.substring(0, app.input.length - 1) + case _: KeyCode.Esc => app.input_mode = InputMode.Normal; + case _ => () + } + } + case _ => () + } + } + + def ui(f: Frame, app: App): Unit = { + val chunks = Layout( + direction = Direction.Vertical, + margin = Margin(2), + constraints = Array(Constraint.Length(1), Constraint.Length(3), Constraint.Min(5)) + ).split(f.size) + + val (msg, style) = app.input_mode match { + case InputMode.Normal => + ( + Text.from( + Span.nostyle("Press "), + Span.styled("q", Style.DEFAULT.addModifier(Modifier.BOLD)), + Span.nostyle(" to exit, "), + Span.styled("e", Style.DEFAULT.addModifier(Modifier.BOLD)), + Span.nostyle(" to start editing.") + ), + Style.DEFAULT.addModifier(Modifier.RAPID_BLINK) + ) + case InputMode.Editing => + ( + Text.from( + Span.nostyle("Press "), + Span.styled("Esc", Style.DEFAULT.addModifier(Modifier.BOLD)), + Span.nostyle(" to stop editing, "), + Span.styled("Enter", Style.DEFAULT.addModifier(Modifier.BOLD)), + Span.nostyle(" to record the message") + ), + Style.DEFAULT + ) + } + val text = msg.overwrittenStyle(style) + + val help_message = ParagraphWidget(text = text) + f.renderWidget(help_message, chunks(0)) + + val input = ParagraphWidget( + text = Text.nostyle(app.input), + block = Some(BlockWidget(borders = Borders.ALL, title = Some(Spans.nostyle("Input")))), + style = app.input_mode match { + case InputMode.Normal => Style.DEFAULT + case InputMode.Editing => Style.DEFAULT.fg(Color.Yellow) + } + ) + f.renderWidget(input, chunks(1)) + + app.input_mode match { + case InputMode.Normal => + // Hide the cursor. `Frame` does this by default, so we don't need to do anything here + () + + case InputMode.Editing => + // Make the cursor visible and ask tui-rs to put it at the specified coordinates after rendering + f.setCursor( + // Put cursor past the end of the input text + x = chunks(1).x + Grapheme(app.input).width + 1, + // Move one line down, from the border to the input line + y = chunks(1).y + 1 + ) + } + + val items: Array[ListWidget.Item] = + app.messages.zipWithIndex.map { case (m, i) => ListWidget.Item(content = Text.nostyle(s"$i: $m")) } + + val messages = + ListWidget( + items = items, + block = Some(BlockWidget(borders = Borders.ALL, title = Some(Spans.nostyle("Messages")))) + ) + f.renderWidget(messages, chunks(2)) + } +} |
