<commit_before>Class {
	#name : #BlGlutinHost,
	#superclass : #BlHost,
	#classVars : [
		'EventsSensor',
		'HostSpaceRegistry',
		'HostSpaceRegistryMutex',
		'UIProcess',
		'UserInterruptEventHandler'
	],
	#category : #'BlocHost-Glutin-Host'
}

{ #category : #'mutual exclusion' }
BlGlutinHost class >> critical: aBlock [
	HostSpaceRegistryMutex ifNil: [ HostSpaceRegistryMutex := Semaphore forMutualExclusion ].
	HostSpaceRegistryMutex critical: aBlock
]

{ #category : #example }
BlGlutinHost class >> example [
	| universe space |
	BlUniverse reset.

	Bloc preferableSpartaCanvas: BlSpartaSkiaCanvasBuilder.

	space := BlSpace new.
	space host: self new.
	space title: 'Glutin Window'.
	space addChild: (BlElement new
		background: Color blue;
		when: BlClickEvent do: [
			GlutinEventsFetcher shutDown: false.
			GlutinEventsFetcher startUp: false ]).
	space show
]

{ #category : #'api - ui process' }
BlGlutinHost class >> forceResumeOfUIProcess: aProcess [
	UIProcess := aProcess.
	UIProcess resume
]

{ #category : #'api - ui process' }
BlGlutinHost class >> forceStartNewUIProcess [
	UIProcess := [
		[
			BlParallelUniverse glutin pulse.
			2 milliSeconds wait
		] repeat.

	] forkAt: Processor userSchedulingPriority named: 'Bloc UI Process'
]

{ #category : #'private - windows' }
BlGlutinHost class >> hostForWindow: aWindow do: aBlock [
	self critical: [
		self spaceRegistry
			at: aWindow id
			ifPresent: aBlock ]
]

{ #category : #'class initialization' }
BlGlutinHost class >> initialize [
	EventsSensor := BlGlutinWindowEventsSensor new.
	UserInterruptEventHandler := GlutinUserInterruptHandler new uiProcessBlock: [
		| process |
		process := nil.
		BlGlutinHost uiProcessDo: [ :aUIProcess | process := aUIProcess ].
		process ]
]

{ #category : #'api - lifecycle' }
BlGlutinHost class >> isRunning [
	<return: #Boolean>

	self uiProcessDo: [ :aUIProcess | ^ aUIProcess isTerminated not ].
	^ false
]

{ #category : #'driver selection' }
BlGlutinHost class >> isSupported [
	"Only works in headless vm"
	^ Smalltalk os windowSystemName isNil or: [ Smalltalk os windowSystemName = 'null' ]
]

{ #category : #'driver selection' }
BlGlutinHost class >> label [
	"Return a host name that we can refer to. May be used for settings"
	<return: #String>

	^ 'Glutin'
]

{ #category : #'driver selection' }
BlGlutinHost class >> priority [
	"Return host priority as positive number which influences host order
	and selection of a default host.
	Lower value - more likely host becomes a default"
	<return: #Number>
	
	^ 1
]

{ #category : #private }
BlGlutinHost class >> spaceRegistry [
	^ HostSpaceRegistry ifNil: [ HostSpaceRegistry := WeakIdentityValueDictionary new ]
]

{ #category : #'api - lifecycle' }
BlGlutinHost class >> start [
	self forceStartNewUIProcess.

	GlutinEventsFetcher default
		addEventHandler: UserInterruptEventHandler;
		addEventHandler: EventsSensor.
	GlutinEventsFetcher install
]

{ #category : #'api - lifecycle' }
BlGlutinHost class >> stop [
	| aUIProcess |

	aUIProcess := UIProcess.
	UIProcess := nil.
	aUIProcess ifNotNil: #terminate
]

{ #category : #'api - ui process' }
BlGlutinHost class >> terminateUIProcess [
	| aProcessToTerminate |
	
	self uiProcessDo: [ :aProcess | aProcessToTerminate := aProcess ].
	UIProcess := nil.
	aProcessToTerminate terminate
	
	"if called from UI thread nothing past this line will be executed"
]

{ #category : #'api - ui process' }
BlGlutinHost class >> uiProcessDo: aBlock [
	UIProcess ifNotNil: aBlock
]

{ #category : #example }
BlGlutinHost class >> world [
	| universe space |
	BlUniverse reset.

	Bloc preferableSpartaCanvas: BlSpartaSkiaCanvasBuilder.

	space := BlSpace new.
	space extent: 1200@800.
	space host: self new.
	space title: 'Morph World'.
	space addChild: (BlMorphicWorldEmbeddingElement new beMain).
	space show
]

{ #category : #'host - api' }
BlGlutinHost >> createHostSpaceFor: aSpace [
	"Create and assign a new oswindow host space for given bloc space"
	| aHostSpace |

	self
		assert: [ aSpace hasHostSpace not ]
		description: [ 'Space must not have a host!' ].
	
	aHostSpace := self createWindowSpaceFor: aSpace.

	aSpace hostSpace: aHostSpace
]

{ #category : #private }
BlGlutinHost >> createWindowSpaceFor: aSpace [<commit_msg>[feenkcom/gtoolkit#585] remove obsolete BlGlutinHost examples<commit_after>Class {
	#name : #BlGlutinHost,
	#superclass : #BlHost,
	#classVars : [
		'EventsSensor',
		'HostSpaceRegistry',
		'HostSpaceRegistryMutex',
		'UIProcess',
		'UserInterruptEventHandler'
	],
	#category : #'BlocHost-Glutin-Host'
}

{ #category : #'mutual exclusion' }
BlGlutinHost class >> critical: aBlock [
	HostSpaceRegistryMutex ifNil: [ HostSpaceRegistryMutex := Semaphore forMutualExclusion ].
	HostSpaceRegistryMutex critical: aBlock
]

{ #category : #'api - ui process' }
BlGlutinHost class >> forceResumeOfUIProcess: aProcess [
	UIProcess := aProcess.
	UIProcess resume
]

{ #category : #'api - ui process' }
BlGlutinHost class >> forceStartNewUIProcess [
	UIProcess := [
		[
			BlParallelUniverse glutin pulse.
			2 milliSeconds wait
		] repeat.

	] forkAt: Processor userSchedulingPriority named: 'Bloc UI Process'
]

{ #category : #'private - windows' }
BlGlutinHost class >> hostForWindow: aWindow do: aBlock [
	self critical: [
		self spaceRegistry
			at: aWindow id
			ifPresent: aBlock ]
]

{ #category : #'class initialization' }
BlGlutinHost class >> initialize [
	EventsSensor := BlGlutinWindowEventsSensor new.
	UserInterruptEventHandler := GlutinUserInterruptHandler new uiProcessBlock: [
		| process |
		process := nil.
		BlGlutinHost uiProcessDo: [ :aUIProcess | process := aUIProcess ].
		process ]
]

{ #category : #'api - lifecycle' }
BlGlutinHost class >> isRunning [
	<return: #Boolean>

	self uiProcessDo: [ :aUIProcess | ^ aUIProcess isTerminated not ].
	^ false
]

{ #category : #'driver selection' }
BlGlutinHost class >> isSupported [
	"Only works in headless vm"
	^ Smalltalk os windowSystemName isNil or: [ Smalltalk os windowSystemName = 'null' ]
]

{ #category : #'driver selection' }
BlGlutinHost class >> label [
	"Return a host name that we can refer to. May be used for settings"
	<return: #String>

	^ 'Glutin'
]

{ #category : #'driver selection' }
BlGlutinHost class >> priority [
	"Return host priority as positive number which influences host order
	and selection of a default host.
	Lower value - more likely host becomes a default"
	<return: #Number>
	
	^ 1
]

{ #category : #private }
BlGlutinHost class >> spaceRegistry [
	^ HostSpaceRegistry ifNil: [ HostSpaceRegistry := WeakIdentityValueDictionary new ]
]

{ #category : #'api - lifecycle' }
BlGlutinHost class >> start [
	self forceStartNewUIProcess.

	GlutinEventsFetcher default
		addEventHandler: UserInterruptEventHandler;
		addEventHandler: EventsSensor.
	GlutinEventsFetcher install
]

{ #category : #'api - lifecycle' }
BlGlutinHost class >> stop [
	| aUIProcess |

	aUIProcess := UIProcess.
	UIProcess := nil.
	aUIProcess ifNotNil: #terminate
]

{ #category : #'api - ui process' }
BlGlutinHost class >> terminateUIProcess [
	| aProcessToTerminate |
	
	self uiProcessDo: [ :aProcess | aProcessToTerminate := aProcess ].
	UIProcess := nil.
	aProcessToTerminate terminate
	
	"if called from UI thread nothing past this line will be executed"
]

{ #category : #'api - ui process' }
BlGlutinHost class >> uiProcessDo: aBlock [
	UIProcess ifNotNil: aBlock
]

{ #category : #'host - api' }
BlGlutinHost >> createHostSpaceFor: aSpace [
	"Create and assign a new oswindow host space for given bloc space"
	| aHostSpace |

	self
		assert: [ aSpace hasHostSpace not ]
		description: [ 'Space must not have a host!' ].
	
	aHostSpace := self createWindowSpaceFor: aSpace.

	aSpace hostSpace: aHostSpace
]

{ #category : #private }
BlGlutinHost >> createWindowSpaceFor: aSpace [
{'fraction_non_alphanumeric': 0.1038994356080041, 'fraction_numerical': 0.0017957927142124167, 'mean_word_length': 4.510247349823322, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 77, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3421286', 'n_tokens_mistral': 2653, 'n_tokens_neox': 2569, 'n_words': 710}