From f61e17de9c06f538b165ddf26d24c12973fb7f92 Mon Sep 17 00:00:00 2001 From: Dany LE Date: Tue, 16 Aug 2022 00:59:35 +0200 Subject: [PATCH] rendering improvement --- Diya/DiyaApplicationLauncher.class.st | 75 ++++++++++++++------------- Diya/DiyaApplicationModel.class.st | 27 ++++++---- Diya/DiyaBoot.class.st | 2 +- Diya/DiyaDefaultAppLoader.class.st | 16 +++--- Diya/DiyaDefaultSystemLoader.class.st | 21 ++++++++ Diya/DiyaExampleApp.class.st | 23 ++++++-- Diya/DiyaLine.class.st | 4 +- Diya/DiyaLoader.class.st | 43 ++++++++++++--- Diya/DiyaNode.class.st | 48 +++++++++++------ Diya/DiyaRectangle.class.st | 8 +-- Diya/DiyaRendererContext.class.st | 9 +++- Diya/DiyaRootNode.class.st | 9 +++- 12 files changed, 192 insertions(+), 93 deletions(-) create mode 100644 Diya/DiyaDefaultSystemLoader.class.st diff --git a/Diya/DiyaApplicationLauncher.class.st b/Diya/DiyaApplicationLauncher.class.st index 373c6ae..d5d6807 100644 --- a/Diya/DiyaApplicationLauncher.class.st +++ b/Diya/DiyaApplicationLauncher.class.st @@ -19,9 +19,9 @@ DiyaApplicationLauncher >> bindGlobalEvent [ |pointer | pointer := node addNode: (DiyaCircle r: 10) at: 200@200. pointer styleName: #pointer. - node on: #keydown do:[:e| self stdlog: 'keydown...'. running := false.]. - node on: #quit do: [:e| running := false]. - node on: #(fingerdown fingermotion mousemotion) do:[:e| + target on: #keydown do:[:e| self stdlog: 'keydown...'. running := false.]. + target on: #quit do: [:e| running := false]. + target on: #(fingerdown fingermotion mousemotion) do:[:e| pointer position: e mapped worldPosition. DiyaRenderer mouse: (e mapped x) @ (e mapped y). ]. @@ -33,37 +33,7 @@ DiyaApplicationLauncher >> defaultApplication [ ] { #category : #initialization } -DiyaApplicationLauncher >> initLoader [ - -] - -{ #category : #initialization } -DiyaApplicationLauncher >> initialize [ - super initialize. - node := DiyaRenderer root. - currapp := nil. -] - -{ #category : #initialization } -DiyaApplicationLauncher >> launch: app [ - currapp ifNotNil: [ - currapp quit. - node empty. - ]. - currapp := app uniqueInstance. - self context assets: currapp am. - self appNode addNode: currapp loader node. - currapp onloaded:[ - self appNode empty. - currapp node visibility: false. - self appNode addNode: currapp node. - currapp node visibility: true. - self stdlog: 'Application LOADED'. - ]. -] - -{ #category : #initialization } -DiyaApplicationLauncher >> onloaded: aBlock [ +DiyaApplicationLauncher >> defineLayout [ DiyaUIThemesManager uniqueInstance currentTheme define: #fps_text styles: { #color -> Color red. @@ -81,9 +51,42 @@ DiyaApplicationLauncher >> onloaded: aBlock [ txtFPS extent: 80@40. txtFPS styleName: #fps_text. self bindGlobalEvent. + self loadNode. +] + +{ #category : #initialization } +DiyaApplicationLauncher >> initialize [ + super initialize. + node := DiyaCompositeNode new. + currapp := nil. +] + +{ #category : #initialization } +DiyaApplicationLauncher >> launch: app [ + currapp ifNotNil: [ + currapp quit. + ]. + currapp := app uniqueInstance. + self context assets: currapp am. + currapp target: self appNode. + currapp onloaded:[ + self stdlog: 'Application LOADED'. + ]. +] + +{ #category : #initialization } +DiyaApplicationLauncher >> onloaded: aBlock [ + |loader| running := true. - self launch: self defaultApplication. - aBlock value. + loader := DiyaDefaultSystemLoader on: target. + loader job: [ DiyaFontManager uniqueInstance loadFonts. ] name: 'Loading fonts...'. + loader job: [ self defineLayout ] name: 'Define layout...'. + loader onloaded: [ + node children do:[:c| target addNode: c at: c position]. + node := target. + aBlock value. + self launch: self defaultApplication. + ] ] { #category : #accessing } diff --git a/Diya/DiyaApplicationModel.class.st b/Diya/DiyaApplicationModel.class.st index 13d502e..d4720b3 100644 --- a/Diya/DiyaApplicationModel.class.st +++ b/Diya/DiyaApplicationModel.class.st @@ -4,7 +4,8 @@ Class { #instVars : [ 'node', 'am', - 'loader' + 'target', + 'context' ], #category : #'Diya-Applications' } @@ -24,20 +25,20 @@ DiyaApplicationModel >> context [ ^DiyaRenderer ] -{ #category : #initialization } -DiyaApplicationModel >> initLoader [ - self subclassResponsibility -] - { #category : #initialization } DiyaApplicationModel >> initialize [ super initialize. - self initLoader. + context := DiyaRenderer ] -{ #category : #accessing } -DiyaApplicationModel >> loader [ - ^ loader +{ #category : #'as yet unclassified' } +DiyaApplicationModel >> loadNode [ + |pseudoRoot| + pseudoRoot := DiyaRootNode new. + pseudoRoot addNode: node. + pseudoRoot processQueue do:[:el| + el process + ]. ] { #category : #accessing } @@ -52,5 +53,11 @@ DiyaApplicationModel >> onloaded: aBlock [ { #category : #accessing } DiyaApplicationModel >> quit [ + node empty. self cleanup ] + +{ #category : #initialization } +DiyaApplicationModel >> target: aNode [ + target := aNode. +] diff --git a/Diya/DiyaBoot.class.st b/Diya/DiyaBoot.class.st index 44d89bc..1e461ec 100644 --- a/Diya/DiyaBoot.class.st +++ b/Diya/DiyaBoot.class.st @@ -83,7 +83,6 @@ DiyaBoot >> init [ Smalltalk globals at: #DiyaDisplay put:display. Smalltalk globals at: #DiyaSystemSettings put: DiyaSettings uniqueInstance. Smalltalk globals at: #DiyaSystemClock put: DiyaClock uniqueInstance. - DiyaFontManager uniqueInstance loadFonts. ] { #category : #events } @@ -102,6 +101,7 @@ DiyaBoot >> render [ "Init the Open GL view port and enable 2D texture" OpenGL viewportX: 0 Y:0 W: display w H: display h. OpenGL enable: GL_TEXTURE_2D. + launcher target: DiyaRenderer root. launcher onloaded: [self stdlog: 'Launcher loaded']. [ launcher running ] whileTrue: [ DiyaSystemClock tick. diff --git a/Diya/DiyaDefaultAppLoader.class.st b/Diya/DiyaDefaultAppLoader.class.st index bcabee5..f28befc 100644 --- a/Diya/DiyaDefaultAppLoader.class.st +++ b/Diya/DiyaDefaultAppLoader.class.st @@ -1,20 +1,20 @@ Class { #name : #DiyaDefaultAppLoader, - #superclass : #DiyaLoader, + #superclass : #DiyaDefaultSystemLoader, #instVars : [ - 'progress', 'label' ], #category : #'Diya-Applications' } { #category : #initialization } -DiyaDefaultAppLoader >> init [ - progress := node addNode: (DiyaLoadingBar new) at: 20@50. - progress extent: 420 @ 20. - label := node addNode: (DiyaText new) at: 20@80. - label extent: 420 @ 20. - label inlineStyle: #xAlign value: #center +DiyaDefaultAppLoader >> updateLayout [ + super updateLayout. + label ifNil:[ + label := node addNode: (DiyaText new) at: (progress position + (0@25)). + label inlineStyle: #xAlign value: #center + ]. + label extent: (progress extent x) @ 40. ] { #category : #scheduling } diff --git a/Diya/DiyaDefaultSystemLoader.class.st b/Diya/DiyaDefaultSystemLoader.class.st new file mode 100644 index 0000000..1ea11b5 --- /dev/null +++ b/Diya/DiyaDefaultSystemLoader.class.st @@ -0,0 +1,21 @@ +Class { + #name : #DiyaDefaultSystemLoader, + #superclass : #DiyaLoader, + #instVars : [ + 'progress' + ], + #category : #'Diya-Applications' +} + +{ #category : #initialization } +DiyaDefaultSystemLoader >> updateLayout [ + |xtent| + xtent := DiyaRenderer resolution. + progress ifNil:[progress := node addNode: (DiyaLoadingBar new) at: 20@((xtent y >> 1) - 50)]. + progress extent: (xtent x - 40) @ 20. +] + +{ #category : #scheduling } +DiyaDefaultSystemLoader >> updateProgress: name percent: p [ + progress percent: p +] diff --git a/Diya/DiyaExampleApp.class.st b/Diya/DiyaExampleApp.class.st index e443c04..1390471 100644 --- a/Diya/DiyaExampleApp.class.st +++ b/Diya/DiyaExampleApp.class.st @@ -1,6 +1,9 @@ Class { #name : #DiyaExampleApp, #superclass : #DiyaBaseApplication, + #instVars : [ + 'loader' + ], #category : #'Diya-Applications' } @@ -12,6 +15,7 @@ DiyaExampleApp >> cleanup [ { #category : #accessing } DiyaExampleApp >> defineNodes [ |node2 node1 img ell label icon button texture loading| + node := DiyaCompositeNode new. texture := DiyaImageTex new. label := node addNode: (DiyaLabel new) at: 10@40. label extent: 250@24. @@ -159,18 +163,27 @@ DiyaExampleApp >> defineStyleSheet [ } ] -{ #category : #initialization } -DiyaExampleApp >> initLoader [ - loader := DiyaDefaultAppLoader new. +{ #category : #accessing } +DiyaExampleApp >> initialize [ + super initialize. + loader := nil + ] { #category : #accessing } DiyaExampleApp >> onloaded: aBlock [ + loader ifNil: [ loader := DiyaDefaultAppLoader on: target ]. loader job: [ self defineStyleSheet ] name: 'Initializing themes...'. loader job: [ self defineNodes. - self node forceReload + self loadNode. ] name: 'Initializing UI elements...'. - loader onloaded: aBlock + loader onloaded: [ + node children do:[:e| + target addNode: e at: e position. + node := target. + ]. + aBlock value + ]. ] diff --git a/Diya/DiyaLine.class.st b/Diya/DiyaLine.class.st index 0a868c2..a6ea8e5 100644 --- a/Diya/DiyaLine.class.st +++ b/Diya/DiyaLine.class.st @@ -94,8 +94,8 @@ DiyaLine >> process [ at: 3 put: 0.0; at: 4 put: 0.0; - at: 5 put: extent x; - at: 6 put: extent y; + at: 5 put: extent x asFloat; + at: 6 put: extent y asFloat; at: 7 put: 0.0; at: 8 put: 0.0. ^true diff --git a/Diya/DiyaLoader.class.st b/Diya/DiyaLoader.class.st index 30785ad..39361ea 100644 --- a/Diya/DiyaLoader.class.st +++ b/Diya/DiyaLoader.class.st @@ -3,26 +3,38 @@ Class { #superclass : #DiyaBaseObject, #instVars : [ 'node', - 'jobs' + 'jobs', + 'target' ], #category : #'Diya-Applications' } +{ #category : #'instance creation' } +DiyaLoader class >> on: target [ + ^ self new target: target; yourself +] + { #category : #scheduling } DiyaLoader >> executeJobs: callback [ + "target visibility: false." + target empty. + target addNode: node. + "target visibility: true". + node visibility: true. + self updateLayout. + 500 milliSeconds wait. + self job: [ 500 milliSeconds wait. ] name: 'finishing' . jobs withIndexDo: [ :job :i| self updateProgress: job key percent: ((i - 1) * 100 / (jobs size)) asInteger. job value value. ]. jobs := OrderedCollection new. self updateProgress: 'Finishing...' percent: 100. - 500 milliSeconds wait. + + node visibility: false. + target empty. callback value. -] - -{ #category : #initialization } -DiyaLoader >> init [ - self subclassResponsibility + target visibility: true. ] { #category : #initialization } @@ -30,7 +42,7 @@ DiyaLoader >> initialize [ super initialize. node := DiyaCompositeNode new. jobs := OrderedCollection new. - self init. + target := nil. ] { #category : #scheduling } @@ -48,6 +60,21 @@ DiyaLoader >> onloaded: aBlock [ [ self executeJobs: aBlock ] fork"At: Processor userBackgroundPriority". ] +{ #category : #accessing } +DiyaLoader >> target [ + ^ target +] + +{ #category : #accessing } +DiyaLoader >> target: anObject [ + target := anObject +] + +{ #category : #initialization } +DiyaLoader >> updateLayout [ + self subclassResponsibility +] + { #category : #scheduling } DiyaLoader >> updateProgress: name percent: p [ self subclassResponsibility diff --git a/Diya/DiyaNode.class.st b/Diya/DiyaNode.class.st index d4f973a..fd95839 100644 --- a/Diya/DiyaNode.class.st +++ b/Diya/DiyaNode.class.st @@ -49,12 +49,12 @@ DiyaNode >> ? styleAttr [ ^ parent ? styleAttr ] -{ #category : #accessing } +{ #category : #'add/remove' } DiyaNode >> addNode: node [ ^self addNode: node at: 0@0 ] -{ #category : #accessing } +{ #category : #'add/remove' } DiyaNode >> addNode: node at: pos [ children ifNil: [ ^self ]. node parent: self. @@ -82,6 +82,13 @@ DiyaNode >> draw [ { #category : #requirements } DiyaNode >> empty [ + children ifNotNil: [ + children do:[:c| + c root: nil. + c setClean. + c visibility: false. + ] + ]. children := OrderedCollection new. ] @@ -90,15 +97,6 @@ DiyaNode >> extent [ ^ self subclassResponsibility ] -{ #category : #processing } -DiyaNode >> forceReload [ - self process. - children ifNotNil: [ - children do:[:c| - c forceReload - ]] -] - { #category : #accessing } DiyaNode >> id [ ^ id @@ -183,28 +181,42 @@ DiyaNode >> register: aBlock to: eventName [ ] -{ #category : #removing } +{ #category : #'add/remove' } DiyaNode >> remove [ - self setClean. - root := nil. parent ifNotNil: [ parent removeChild: self ] ] -{ #category : #removing } +{ #category : #'add/remove' } DiyaNode >> removeChild: c [ + c setClean. + c root: nil. + c visibility: false. children ifNotNil: [ children remove: c ifAbsent:[ ]] ] { #category : #rendering } DiyaNode >> render [ visibility ifFalse:[^self]. - root ifNil: [ ^self ]. shader ifNotNil: [self setUpShader]. self draw. children ifNil: [ ^self ]. + root ifNil: [ ^self ]. root renderNext: children ] +{ #category : #'add/remove' } +DiyaNode >> replaceChild: aNode with: anotherNode [ + |index| + children ifNil: [ ^ self ]. + index := children indexOf: aNode. + index = 0 ifTrue:[^ self]. + children at: index put: anotherNode. + anotherNode parent: self. + anotherNode root: self root. + anotherNode setDirtyAll. + aNode root: nil. +] + { #category : #accessing } DiyaNode >> root [ ^ root @@ -354,5 +366,7 @@ DiyaNode >> visibility [ { #category : #accessing } DiyaNode >> visibility: anObject [ - visibility := anObject + visibility := anObject. + children ifNotNil: [ + children do:[:c| c visibility: anObject ] ] ] diff --git a/Diya/DiyaRectangle.class.st b/Diya/DiyaRectangle.class.st index 01bea69..f4e85d7 100644 --- a/Diya/DiyaRectangle.class.st +++ b/Diya/DiyaRectangle.class.st @@ -47,16 +47,16 @@ DiyaRectangle >> process [ at: 4 put: 0.0; at: 5 put: 0.0; - at: 6 put: extent y; + at: 6 put: extent y asFloat; at: 7 put: 0.0; at: 8 put: 1.0; - at: 9 put: extent x; - at: 10 put: extent y; + at: 9 put: extent x asFloat; + at: 10 put: extent y asFloat; at: 11 put: 1.0; at: 12 put: 1.0; - at: 13 put: extent x; + at: 13 put: extent x asFloat; at: 14 put: 0.0; at: 15 put: 1.0; at: 16 put: 0.0. diff --git a/Diya/DiyaRendererContext.class.st b/Diya/DiyaRendererContext.class.st index a242a5d..b1a56bc 100644 --- a/Diya/DiyaRendererContext.class.st +++ b/Diya/DiyaRendererContext.class.st @@ -10,7 +10,8 @@ Class { 'projection', 'assets', 'window', - 'root' + 'root', + 'lock' ], #pools : [ 'OpenGLConstants', @@ -79,6 +80,7 @@ DiyaRendererContext >> initialize [ vbo := OpenGLVertexBuffer new. vao := OpenGLVertexArray new. textures := Dictionary new. + lock := Mutex new. vao bind. vbo bind: GL_ARRAY_BUFFER. projection := Array2D identity: 4. @@ -96,6 +98,11 @@ DiyaRendererContext >> initialize [ (OpenGLTexture fromUnit: i - 1) -> nil] . ] +{ #category : #accessing } +DiyaRendererContext >> lock [ + ^ lock +] + { #category : #accessing } DiyaRendererContext >> mouse [ ^ mouse diff --git a/Diya/DiyaRootNode.class.st b/Diya/DiyaRootNode.class.st index 78505d0..eeb132a 100644 --- a/Diya/DiyaRootNode.class.st +++ b/Diya/DiyaRootNode.class.st @@ -62,6 +62,11 @@ DiyaRootNode >> process [ ] +{ #category : #controlling } +DiyaRootNode >> processQueue [ + ^ Q +] + { #category : #testing } DiyaRootNode >> readyForSwap [ ^ R isEmpty @@ -105,10 +110,12 @@ DiyaRootNode >> spinOnce: maxProcessingTime [ Q ifNotEmpty: [ node := Q removeFirst. node process. + "context lock critical: [node process]." ]. R ifNotEmpty: [ node := R removeFirst. - node render. + node render. + "context lock critical: [node render]. " ]. (Q isEmpty and: R isEmpty) ifTrue: [ ^false ]. DiyaSystemSettings renderAtOnce ifTrue: [ ^ true ].