1+ package io .computenode .cyfra .rtrp .surface
2+
3+ import io .computenode .cyfra .rtrp .window .WindowManager
4+ import io .computenode .cyfra .rtrp .window .core .WindowConfig
5+ import io .computenode .cyfra .rtrp .window .core .WindowPosition
6+ import io .computenode .cyfra .rtrp .surface .core .{SurfaceConfig , PresentMode }
7+ import io .computenode .cyfra .vulkan .VulkanContext
8+ import scala .util .{Try , Success , Failure }
9+
10+ // Complete example demonstrating the integrated window + surface system.
11+ object SurfaceIntegrationExample {
12+
13+ def main (args : Array [String ]): Unit = {
14+ println(" === Cyfra Surface Integration Example ===" )
15+
16+ val result = runFullExample()
17+
18+ result match {
19+ case Success (_) =>
20+ println(" Surface integration example completed successfully!" )
21+ case Failure (ex) =>
22+ println(s " Surface integration example failed: ${ex.getMessage}" )
23+ ex.printStackTrace()
24+ }
25+ }
26+
27+ private def runFullExample (): Try [Unit ] = Try {
28+ println(" === Cyfra Surface Integration Example ===\n " )
29+
30+ // Initialize GLFW first
31+ import org .lwjgl .glfw .GLFW
32+ if (! GLFW .glfwInit()) {
33+ throw new RuntimeException (" Failed to initialize GLFW" )
34+ }
35+
36+ try {
37+ // Now create VulkanContext with surface support
38+ val vulkanContext = VulkanContext .withSurfaceSupport()
39+
40+ WindowManager .withVulkanManager(vulkanContext) { manager =>
41+ Try {
42+ setupEventHandlers(manager)
43+ println(" Event handlers configured\n " )
44+
45+ val windowsAndSurfaces = createTestWindows(manager)
46+ println(s " Created ${windowsAndSurfaces.size} window-surface pairs \n " )
47+
48+ inspectSurfaceCapabilities(windowsAndSurfaces)
49+
50+ runMainLoop(manager, windowsAndSurfaces)
51+ println(" Main loop completed\n " )
52+
53+ windowsAndSurfaces.foreach { case (window, surface) =>
54+ testSurfaceRecreation(manager, surface)
55+ }
56+ }
57+ }
58+ } finally {
59+ GLFW .glfwTerminate()
60+ }
61+ }
62+
63+ private def setupEventHandlers (manager : WindowManager ): Unit = {
64+ // Window event handlers
65+ manager.onWindowResize { event =>
66+ println(s " Window ${event.windowId} resized to ${event.width}x ${event.height}" )
67+ }
68+
69+ manager.onWindowClose { event =>
70+ println(s " Window ${event.windowId} close requested " )
71+ }
72+
73+ manager.onKeyPress { event =>
74+ println(s " Key ${event.key.code} pressed in window ${event.windowId}" )
75+ }
76+
77+ manager.onMouseClick { event =>
78+ println(s " Mouse button ${event.button.code} clicked at ( ${event.x.toInt}, ${event.y.toInt}) in window ${event.windowId}" )
79+ }
80+
81+ // Surface event handlers
82+ manager.onSurfaceCreated { event =>
83+ println(s " Surface ${event.surfaceId} created for window ${event.windowId}" )
84+ val caps = event.capabilities
85+ println(s " Formats: ${caps.supportedFormats.size}, Present modes: ${caps.supportedPresentModes.size}" )
86+ }
87+
88+ manager.onSurfaceDestroyed { event =>
89+ println(s " Surface ${event.surfaceId} destroyed for window ${event.windowId}" )
90+ }
91+
92+ manager.onSurfaceLost { event =>
93+ println(s " Surface ${event.surfaceId} lost for window ${event.windowId}: ${event.error}" )
94+ }
95+ }
96+
97+ private def createTestWindows (manager : WindowManager ): List [(io.computenode.cyfra.rtrp.window.core.Window , io.computenode.cyfra.rtrp.surface.core.RenderSurface )] = {
98+ val configs = List (
99+ // Main window - gaming configuration
100+ (WindowConfig (
101+ width = 1024 ,
102+ height = 768 ,
103+ title = " Main Window" ,
104+ position = Some (WindowPosition .Centered )
105+ ), SurfaceConfig .gaming),
106+
107+ // Secondary window - quality configuration
108+ (WindowConfig (
109+ width = 800 ,
110+ height = 600 ,
111+ title = " Secondary Window" ,
112+ position = Some (WindowPosition .Fixed (100 , 100 ))
113+ ), SurfaceConfig .quality),
114+
115+ // Tool window - low latency configuration
116+ (WindowConfig (
117+ width = 400 ,
118+ height = 300 ,
119+ title = " Tool Window" ,
120+ position = Some (WindowPosition .Fixed (200 , 200 ))
121+ ), SurfaceConfig .lowLatency)
122+ )
123+
124+ manager.createWindowsWithSurfaces(configs) match {
125+ case Success (pairs) => pairs
126+ case Failure (ex) =>
127+ println(s " Failed to create windows: ${ex.getMessage}" )
128+ List .empty
129+ }
130+ }
131+
132+ private def inspectSurfaceCapabilities (windowSurfacePairs : List [(io.computenode.cyfra.rtrp.window.core.Window , io.computenode.cyfra.rtrp.surface.core.RenderSurface )]): Unit = {
133+ windowSurfacePairs.foreach { case (window, surface) =>
134+ println(s " \n Surface ${surface.id} (Window: ${window.properties.title}): " )
135+
136+ surface.getCapabilities() match {
137+ case Success (caps) =>
138+ println(s " Current size: ${caps.currentExtent}" )
139+ println(s " Size range: ${caps.minImageExtent} to ${caps.maxImageExtent}" )
140+ println(s " Image count: ${caps.minImageCount} to ${caps.maxImageCount}" )
141+ println(s " Formats ( ${caps.supportedFormats.size}): ${caps.supportedFormats.take(3 ).mkString(" , " )}${if (caps.supportedFormats.size > 3 ) " ..." else " " }" )
142+ println(s " Present modes ( ${caps.supportedPresentModes.size}): ${caps.supportedPresentModes.mkString(" , " )}" )
143+ println(s " Alpha support: ${caps.supportsAlpha}" )
144+ println(s " Transform support: ${caps.supportsTransform}" )
145+
146+ case Failure (ex) =>
147+ println(s " Failed to get capabilities: ${ex.getMessage}" )
148+ }
149+ }
150+ }
151+
152+ private def runMainLoop (
153+ manager : WindowManager ,
154+ windowSurfacePairs : List [(io.computenode.cyfra.rtrp.window.core.Window , io.computenode.cyfra.rtrp.surface.core.RenderSurface )]
155+ ): Unit = {
156+ var frameCount = 0
157+ val maxFrames = 300 // 5 seconds at 60fps
158+ val windows = windowSurfacePairs.map(_._1)
159+ val surfaces = windowSurfacePairs.map(_._2)
160+
161+ while (frameCount < maxFrames && windows.exists(! _.shouldClose)) {
162+ // Poll and handle events
163+ manager.pollAndDispatchEvents() match {
164+ case Success (_) => // Events handled successfully
165+ case Failure (ex) => println(s " Warning: Event polling failed: ${ex.getMessage}" )
166+ }
167+
168+ // Simulate rendering work
169+ if (frameCount % 60 == 0 ) {
170+ val seconds = frameCount / 60 + 1
171+ val validSurfaces = surfaces.count(_.isValid)
172+ val openWindows = windows.count(! _.shouldClose)
173+ println(s " ${seconds}s: ${openWindows} windows open, ${validSurfaces} surfaces valid " )
174+
175+ // Print surface manager statistics
176+ manager.getSurfaceManager().foreach { surfMgr =>
177+ val stats = surfMgr.getStatistics()
178+ println(s " Surface stats: ${stats}" )
179+ }
180+ }
181+
182+ frameCount += 1
183+ Thread .sleep(16 ) // ~60 FPS
184+ }
185+
186+ println(" Main loop completed" )
187+ }
188+
189+ private def testSurfaceRecreation (manager : WindowManager , surface : io.computenode.cyfra.rtrp.surface.core.RenderSurface ): Unit = {
190+ println(s " Testing recreation of surface ${surface.id}... " )
191+
192+ manager.getSurfaceManager() match {
193+ case Some (surfMgr) =>
194+ surfMgr.recreateSurface(surface.windowId, " Test recreation" ) match {
195+ case Success (_) =>
196+ println(" Surface recreation successful" )
197+ case Failure (ex) =>
198+ println(s " Surface recreation failed: ${ex.getMessage}" )
199+ }
200+ case None =>
201+ println(" No surface manager available" )
202+ }
203+ }
204+ }
0 commit comments