-
Notifications
You must be signed in to change notification settings - Fork 14
Adding cyfra-rtrp Module #51
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from 1 commit
f3438e1
b2029b7
524557b
0096f76
4146222
903f629
7ddd112
41267ce
6392ce7
f9eff8a
7ae654f
5a6aadc
fded0a8
3a12340
5d3ed13
ded1a92
9f5e6a1
8b7038b
20c5844
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,107 @@ | ||
| package io.computenode.cyfra.rtrp.window | ||
|
|
||
| import io.computenode.cyfra.window.core._ | ||
| import io.computenode.cyfra.window.platform.GLFWWindowSystem | ||
| import scala.util.{Try, Success, Failure} | ||
|
|
||
| class WindowManager { | ||
| private var windowSystem: Option[WindowSystem] = None | ||
| private var eventHandlers: Map[Class[_ <: WindowEvent], WindowEvent => Unit] = Map.empty | ||
|
|
||
| def initialize(): Try[Unit] = { | ||
| if (windowSystem.isDefined) { | ||
| return Failure(new IllegalStateException("WindowManager already initialized")) | ||
| } | ||
|
|
||
| val glfwSystem = new GLFWWindowSystem() | ||
| glfwSystem.initialize().map { _ => | ||
| windowSystem = Some(glfwSystem) | ||
| } | ||
| } | ||
|
|
||
| def shutdown(): Try[Unit] = { | ||
| windowSystem match { | ||
| case Some(system) => | ||
| val result = system.shutdown() | ||
| windowSystem = None | ||
| result | ||
| case None => | ||
| Success(()) | ||
| } | ||
| } | ||
|
|
||
| def createWindow(): Try[Window] = { | ||
| createWindow(WindowConfig()) | ||
| } | ||
|
|
||
| def createWindow(config: WindowConfig): Try[Window] = { | ||
| windowSystem match { | ||
| case Some(system) => system.createWindow(config) | ||
| case None => Failure(new IllegalStateException("WindowManager not initialized")) | ||
| } | ||
| } | ||
|
|
||
| def createWindow(configure: WindowConfig => WindowConfig): Try[Window] = { | ||
| val config = configure(WindowConfig()) | ||
| createWindow(config) | ||
| } | ||
|
|
||
| def pollAndDispatchEvents(): Try[Unit] = { | ||
| windowSystem match { | ||
| case Some(system) => | ||
| system.pollEvents().map { events => | ||
| events.foreach(dispatchEvent) | ||
| } | ||
| case None => | ||
| Failure(new IllegalStateException("WindowManager not initialized")) | ||
| } | ||
| } | ||
|
|
||
| def onEvent[T <: WindowEvent](eventClass: Class[T])(handler: T => Unit): Unit = { | ||
| eventHandlers = eventHandlers + (eventClass -> handler.asInstanceOf[WindowEvent => Unit]) | ||
| } | ||
|
|
||
| def onWindowClose(handler: WindowEvent.CloseRequested => Unit): Unit = { | ||
| onEvent(classOf[WindowEvent.CloseRequested])(handler) | ||
| } | ||
|
|
||
| def onWindowResize(handler: WindowEvent.Resized => Unit): Unit = { | ||
| onEvent(classOf[WindowEvent.Resized])(handler) | ||
| } | ||
|
|
||
| def onKeyPress(handler: InputEvent.KeyPressed => Unit): Unit = { | ||
| onEvent(classOf[InputEvent.KeyPressed])(handler) | ||
| } | ||
|
|
||
| def onMouseClick(handler: InputEvent.MousePressed => Unit): Unit = { | ||
| onEvent(classOf[InputEvent.MousePressed])(handler) | ||
| } | ||
|
|
||
| def getActiveWindows(): List[Window] = { | ||
| windowSystem.map(_.getActiveWindows()).getOrElse(List.empty) | ||
| } | ||
|
|
||
| def isInitialized: Boolean = windowSystem.isDefined | ||
|
|
||
| private def dispatchEvent(event: WindowEvent): Unit = { | ||
| eventHandlers.get(event.getClass).foreach(_(event)) | ||
| } | ||
| } | ||
|
|
||
| object WindowManager { | ||
|
|
||
| def create(): Try[WindowManager] = { | ||
| val manager = new WindowManager() | ||
| manager.initialize().map(_ => manager) | ||
| } | ||
|
|
||
| def withManager[T](action: WindowManager => Try[T]): Try[T] = { | ||
| create().flatMap { manager => | ||
| try { | ||
| action(manager) | ||
| } finally { | ||
| manager.shutdown() | ||
| } | ||
| } | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,76 @@ | ||
| package io.computenode.cyfra.rtrp.window | ||
|
|
||
| import io.computenode.cyfra.window.core._ | ||
| import scala.util.{Try, Success, Failure} | ||
|
|
||
| object WindowSystemExample { | ||
|
|
||
| def main(args: Array[String]): Unit = { | ||
| println("Starting Window System Example") | ||
|
|
||
| val result = WindowManager.withManager { manager => | ||
| runExample(manager) | ||
| } | ||
|
|
||
| result match { | ||
| case Success(_) => println("Example completed successfully") | ||
| case Failure(ex) => | ||
| println(s"Example failed: ${ex.getMessage}") | ||
| ex.printStackTrace() | ||
| } | ||
| } | ||
|
|
||
| private def runExample(manager: WindowManager): Try[Unit] = Try { | ||
| manager.onWindowClose { event => | ||
| println(s"Window ${event.windowId} close requested") | ||
| } | ||
|
|
||
| manager.onWindowResize { event => | ||
| println(s"Window ${event.windowId} resized to ${event.width}x${event.height}") | ||
| } | ||
|
|
||
| manager.onKeyPress { event => | ||
| println(s"Key pressed: ${event.key.code} in window ${event.windowId}") | ||
| } | ||
|
|
||
| manager.onMouseClick { event => | ||
| println(s"Mouse clicked: button ${event.button.code} at (${event.x}, ${event.y}) in window ${event.windowId}") | ||
| } | ||
|
|
||
| // Create a window | ||
| val window = manager.createWindow { config => | ||
| config.copy( | ||
| width = 1024, | ||
| height = 768, | ||
| title = "Window Example", | ||
| position = Some(WindowPosition.Centered) | ||
| ) | ||
| }.get | ||
|
|
||
| println(s"Created window: ${window.id}") | ||
|
|
||
| // Main loop | ||
| var running = true | ||
| var frameCount = 0 | ||
|
|
||
| while (running && !window.shouldClose) { | ||
|
||
| // Poll and handle events | ||
| manager.pollAndDispatchEvents() | ||
|
|
||
| // Simple frame counter | ||
| frameCount += 1 | ||
| if (frameCount % 60 == 0) { | ||
| println(s"Frame $frameCount - Window active: ${window.isVisible}") | ||
| } | ||
|
|
||
| // Simulate some work (in real, this would be rendering) | ||
| Thread.sleep(16) // ~60 FPS | ||
|
|
||
| if (frameCount >= 1000) { | ||
| running = false | ||
| } | ||
| } | ||
|
|
||
| println("Main loop ended") | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,34 @@ | ||
| package io.computenode.cyfra.window.core | ||
|
|
||
| import scala.util.Try | ||
|
|
||
| // Unique identifier for windows | ||
| case class WindowId(value: Long) extends AnyVal | ||
|
|
||
| // Platform-agnostic window interface | ||
| trait Window { | ||
| def id: WindowId | ||
| def properties: WindowProperties | ||
| def nativeHandle: Long // Platform-specific handle | ||
|
|
||
| // Window operations | ||
| def show(): Try[Unit] | ||
| def hide(): Try[Unit] | ||
| def close(): Try[Unit] | ||
| def focus(): Try[Unit] | ||
| def minimize(): Try[Unit] | ||
| def maximize(): Try[Unit] | ||
| def restore(): Try[Unit] | ||
|
|
||
| // Property changes | ||
| def setTitle(title: String): Try[Unit] | ||
| def setSize(width: Int, height: Int): Try[Unit] | ||
| def setPosition(x: Int, y: Int): Try[Unit] | ||
|
|
||
| // Queries | ||
| def shouldClose: Boolean | ||
| def isVisible: Boolean | ||
| def isFocused: Boolean | ||
| def isMinimized: Boolean | ||
| def isMaximized: Boolean | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,30 @@ | ||
| package io.computenode.cyfra.window.core | ||
|
|
||
| case class WindowConfig( | ||
| width: Int = 800, | ||
| height: Int = 600, | ||
| title: String = "Cyfra Window", | ||
| resizable: Boolean = true, | ||
| decorated: Boolean = true, | ||
| fullscreen: Boolean = false, | ||
| vsync: Boolean = true, | ||
| samples: Int = 1, // MSAA samples | ||
| position: Option[WindowPosition] = None | ||
| ) | ||
|
|
||
| sealed trait WindowPosition | ||
| object WindowPosition { | ||
| case object Centered extends WindowPosition | ||
| case class Fixed(x: Int, y: Int) extends WindowPosition | ||
| case object Default extends WindowPosition | ||
| } | ||
|
|
||
| case class WindowProperties( | ||
| width: Int, | ||
| height: Int, | ||
| title: String, | ||
| visible: Boolean, | ||
| focused: Boolean, | ||
| minimized: Boolean, | ||
| maximized: Boolean | ||
| ) |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,49 @@ | ||
| package io.computenode.cyfra.window.core | ||
|
|
||
| // Base trait for all window events | ||
| sealed trait WindowEvent { | ||
| def windowId: WindowId | ||
| } | ||
|
|
||
|
|
||
| // Window lifecycle events | ||
| object WindowEvent { | ||
| case class Created(windowId: WindowId) extends WindowEvent | ||
| case class Destroyed(windowId: WindowId) extends WindowEvent | ||
| case class CloseRequested(windowId: WindowId) extends WindowEvent | ||
| case class Resized(windowId: WindowId, width: Int, height: Int) extends WindowEvent | ||
| case class Moved(windowId: WindowId, x: Int, y: Int) extends WindowEvent | ||
| case class FocusChanged(windowId: WindowId, focused: Boolean) extends WindowEvent | ||
| case class VisibilityChanged(windowId: WindowId, visible: Boolean) extends WindowEvent | ||
| case class Minimized(windowId: WindowId) extends WindowEvent | ||
| case class Maximized(windowId: WindowId) extends WindowEvent | ||
| case class Restored(windowId: WindowId) extends WindowEvent | ||
| } | ||
|
|
||
|
|
||
| // Input events | ||
| sealed trait InputEvent extends WindowEvent | ||
|
|
||
| object InputEvent { | ||
| case class KeyPressed(windowId: WindowId, key: Key, modifiers: KeyModifiers) extends InputEvent | ||
| case class KeyReleased(windowId: WindowId, key: Key, modifiers: KeyModifiers) extends InputEvent | ||
| case class KeyRepeated(windowId: WindowId, key: Key, modifiers: KeyModifiers) extends InputEvent | ||
| case class CharacterInput(windowId: WindowId, codepoint: Int) extends InputEvent | ||
|
|
||
| case class MousePressed(windowId: WindowId, button: MouseButton, x: Double, y: Double, modifiers: KeyModifiers) extends InputEvent | ||
| case class MouseReleased(windowId: WindowId, button: MouseButton, x: Double, y: Double, modifiers: KeyModifiers) extends InputEvent | ||
| case class MouseMoved(windowId: WindowId, x: Double, y: Double) extends InputEvent | ||
| case class MouseScrolled(windowId: WindowId, xOffset: Double, yOffset: Double) extends InputEvent | ||
| case class MouseEntered(windowId: WindowId) extends InputEvent | ||
| case class MouseExited(windowId: WindowId) extends InputEvent | ||
| } | ||
|
|
||
| case class Key(code: Int) | ||
| case class MouseButton(code: Int) | ||
|
|
||
| case class KeyModifiers( | ||
| shift: Boolean = false, | ||
| ctrl: Boolean = false, | ||
| alt: Boolean = false, | ||
| `super`: Boolean = false | ||
| ) |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,16 @@ | ||
| package io.computenode.cyfra.window.core | ||
|
|
||
| import scala.util.Try | ||
|
|
||
| // Main interface for window system operations | ||
| trait WindowSystem { | ||
|
|
||
| def initialize(): Try[Unit] | ||
| def shutdown(): Try[Unit] | ||
| def createWindow(config: WindowConfig): Try[Window] | ||
| def destroyWindow(window: Window): Try[Unit] | ||
| def pollEvents(): Try[List[WindowEvent]] | ||
| def getActiveWindows(): List[Window] | ||
| def findWindow(id: WindowId): Option[Window] | ||
| def isInitialized: Boolean | ||
| } |
Uh oh!
There was an error while loading. Please reload this page.