diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/RenderWindow.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/RenderWindow.kt index d983aca20..b4a5bcc1d 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/RenderWindow.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/RenderWindow.kt @@ -95,6 +95,8 @@ class RenderWindow( private var slowRendering = profile.performance.slowRendering + lateinit var thread: Thread + private set var renderingState = RenderingStates.RUNNING private set(value) { @@ -128,6 +130,10 @@ class RenderWindow( fun init(latch: CountUpAndDownLatch) { Log.log(LogMessageType.RENDERING_LOADING) { "Creating window..." } + if (this::thread.isInitialized) { + throw IllegalStateException("Thread is already set!") + } + this.thread = Thread.currentThread() val stopwatch = Stopwatch() window.init(connection.profiles.rendering) @@ -209,7 +215,7 @@ class RenderWindow( }) - connection.fireEvent(ResizeWindowEvent(previousSize = Vec2i(0, 0), size = window.size)) + connection.fireEvent(ResizeWindowEvent(this, previousSize = Vec2i(0, 0), size = window.size)) textureManager.dynamicTextures.activate() textureManager.staticTextures.activate() diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/Rendering.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/Rendering.kt index c5576e857..ff70510ed 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/Rendering.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/Rendering.kt @@ -89,7 +89,7 @@ class Rendering(private val connection: PlayConnection) { exception.printStackTrace() try { renderWindow.window.destroy() - connection.fireEvent(WindowCloseEvent(window = renderWindow.window)) + connection.fireEvent(WindowCloseEvent(renderWindow, window = renderWindow.window)) } catch (ignored: Throwable) { } connection.network.disconnect() diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/modding/events/CameraMatrixChangeEvent.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/modding/events/CameraMatrixChangeEvent.kt index 89b1995df..eadaf910d 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/modding/events/CameraMatrixChangeEvent.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/modding/events/CameraMatrixChangeEvent.kt @@ -15,10 +15,9 @@ package de.bixilon.minosoft.gui.rendering.modding.events import de.bixilon.kotlinglm.mat4x4.Mat4 import de.bixilon.minosoft.gui.rendering.RenderWindow -import de.bixilon.minosoft.gui.rendering.Rendering class CameraMatrixChangeEvent( - renderWindow: RenderWindow = Rendering.currentContext!!, + renderWindow: RenderWindow, viewMatrix: Mat4, projectionMatrix: Mat4, viewProjectionMatrix: Mat4, diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/modding/events/CameraPositionChangeEvent.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/modding/events/CameraPositionChangeEvent.kt index e146648d3..9b1db6fdb 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/modding/events/CameraPositionChangeEvent.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/modding/events/CameraPositionChangeEvent.kt @@ -15,10 +15,9 @@ package de.bixilon.minosoft.gui.rendering.modding.events import de.bixilon.kotlinglm.vec3.Vec3 import de.bixilon.minosoft.gui.rendering.RenderWindow -import de.bixilon.minosoft.gui.rendering.Rendering class CameraPositionChangeEvent( - renderWindow: RenderWindow = Rendering.currentContext!!, + renderWindow: RenderWindow, newPosition: Vec3, ) : RenderEvent(renderWindow) { val newPosition: Vec3 = newPosition diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/modding/events/ResizeWindowEvent.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/modding/events/ResizeWindowEvent.kt index 3afe0ceef..8f0a96b47 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/modding/events/ResizeWindowEvent.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/modding/events/ResizeWindowEvent.kt @@ -15,10 +15,9 @@ package de.bixilon.minosoft.gui.rendering.modding.events import de.bixilon.kotlinglm.vec2.Vec2i import de.bixilon.minosoft.gui.rendering.RenderWindow -import de.bixilon.minosoft.gui.rendering.Rendering class ResizeWindowEvent( - renderWindow: RenderWindow = Rendering.currentContext!!, + renderWindow: RenderWindow, val previousSize: Vec2i, val size: Vec2i, ) : RenderEvent(renderWindow) diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/modding/events/VisibilityGraphChangeEvent.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/modding/events/VisibilityGraphChangeEvent.kt index f716baa5f..970378c86 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/modding/events/VisibilityGraphChangeEvent.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/modding/events/VisibilityGraphChangeEvent.kt @@ -14,8 +14,7 @@ package de.bixilon.minosoft.gui.rendering.modding.events import de.bixilon.minosoft.gui.rendering.RenderWindow -import de.bixilon.minosoft.gui.rendering.Rendering class VisibilityGraphChangeEvent( - renderWindow: RenderWindow = Rendering.currentContext!!, + renderWindow: RenderWindow, ) : RenderEvent(renderWindow) diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/modding/events/WindowCloseEvent.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/modding/events/WindowCloseEvent.kt index b59f0955d..3adb0d2bc 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/modding/events/WindowCloseEvent.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/modding/events/WindowCloseEvent.kt @@ -1,6 +1,6 @@ /* * Minosoft - * Copyright (C) 2021 Moritz Zwerger + * Copyright (C) 2020-2022 Moritz Zwerger * * This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. * @@ -14,11 +14,10 @@ package de.bixilon.minosoft.gui.rendering.modding.events import de.bixilon.minosoft.gui.rendering.RenderWindow -import de.bixilon.minosoft.gui.rendering.Rendering import de.bixilon.minosoft.gui.rendering.system.window.BaseWindow import de.bixilon.minosoft.modding.event.events.CancelableEvent class WindowCloseEvent( - renderWindow: RenderWindow = Rendering.currentContext!!, + renderWindow: RenderWindow, val window: BaseWindow, ) : RenderEvent(renderWindow), CancelableEvent diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/modding/events/WindowFocusChangeEvent.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/modding/events/WindowFocusChangeEvent.kt index fd41673e9..080b0386a 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/modding/events/WindowFocusChangeEvent.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/modding/events/WindowFocusChangeEvent.kt @@ -1,6 +1,6 @@ /* * Minosoft - * Copyright (C) 2021 Moritz Zwerger + * Copyright (C) 2020-2022 Moritz Zwerger * * This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. * @@ -14,11 +14,10 @@ package de.bixilon.minosoft.gui.rendering.modding.events import de.bixilon.minosoft.gui.rendering.RenderWindow -import de.bixilon.minosoft.gui.rendering.Rendering import de.bixilon.minosoft.gui.rendering.system.window.BaseWindow class WindowFocusChangeEvent( - renderWindow: RenderWindow = Rendering.currentContext!!, + renderWindow: RenderWindow, val window: BaseWindow, val focused: Boolean, ) : RenderEvent(renderWindow) diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/modding/events/WindowIconifyChangeEvent.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/modding/events/WindowIconifyChangeEvent.kt index 7c800b96a..5005b7250 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/modding/events/WindowIconifyChangeEvent.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/modding/events/WindowIconifyChangeEvent.kt @@ -1,6 +1,6 @@ /* * Minosoft - * Copyright (C) 2021 Moritz Zwerger + * Copyright (C) 2020-2022 Moritz Zwerger * * This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. * @@ -14,11 +14,10 @@ package de.bixilon.minosoft.gui.rendering.modding.events import de.bixilon.minosoft.gui.rendering.RenderWindow -import de.bixilon.minosoft.gui.rendering.Rendering import de.bixilon.minosoft.gui.rendering.system.window.BaseWindow class WindowIconifyChangeEvent( - renderWindow: RenderWindow = Rendering.currentContext!!, + renderWindow: RenderWindow, val window: BaseWindow, val iconified: Boolean, ) : RenderEvent(renderWindow) diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/modding/events/input/MouseMoveEvent.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/modding/events/input/MouseMoveEvent.kt index db7ba1e81..6e4573e2a 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/modding/events/input/MouseMoveEvent.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/modding/events/input/MouseMoveEvent.kt @@ -15,11 +15,10 @@ package de.bixilon.minosoft.gui.rendering.modding.events.input import de.bixilon.kotlinglm.vec2.Vec2d import de.bixilon.minosoft.gui.rendering.RenderWindow -import de.bixilon.minosoft.gui.rendering.Rendering import de.bixilon.minosoft.gui.rendering.modding.events.RenderEvent class MouseMoveEvent( - renderWindow: RenderWindow = Rendering.currentContext!!, + renderWindow: RenderWindow, position: Vec2d, previous: Vec2d, delta: Vec2d, diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/modding/events/input/MouseScrollEvent.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/modding/events/input/MouseScrollEvent.kt index 09d476a4e..91d76646d 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/modding/events/input/MouseScrollEvent.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/modding/events/input/MouseScrollEvent.kt @@ -15,12 +15,11 @@ package de.bixilon.minosoft.gui.rendering.modding.events.input import de.bixilon.kotlinglm.vec2.Vec2d import de.bixilon.minosoft.gui.rendering.RenderWindow -import de.bixilon.minosoft.gui.rendering.Rendering import de.bixilon.minosoft.gui.rendering.modding.events.RenderEvent import de.bixilon.minosoft.modding.event.events.CancelableEvent class MouseScrollEvent( - renderWindow: RenderWindow = Rendering.currentContext!!, + renderWindow: RenderWindow, offset: Vec2d, ) : RenderEvent(renderWindow), CancelableEvent { val offset: Vec2d = offset diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/modding/events/input/RawCharInputEvent.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/modding/events/input/RawCharInputEvent.kt index a1ff1f2e9..840955cd7 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/modding/events/input/RawCharInputEvent.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/modding/events/input/RawCharInputEvent.kt @@ -1,6 +1,6 @@ /* * Minosoft - * Copyright (C) 2021 Moritz Zwerger + * Copyright (C) 2020-2022 Moritz Zwerger * * This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. * @@ -14,10 +14,9 @@ package de.bixilon.minosoft.gui.rendering.modding.events.input import de.bixilon.minosoft.gui.rendering.RenderWindow -import de.bixilon.minosoft.gui.rendering.Rendering import de.bixilon.minosoft.gui.rendering.modding.events.RenderEvent class RawCharInputEvent( - renderWindow: RenderWindow = Rendering.currentContext!!, + renderWindow: RenderWindow, val char: Int, ) : RenderEvent(renderWindow) diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/modding/events/input/RawKeyInputEvent.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/modding/events/input/RawKeyInputEvent.kt index 117021068..300fd9ecc 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/modding/events/input/RawKeyInputEvent.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/modding/events/input/RawKeyInputEvent.kt @@ -1,6 +1,6 @@ /* * Minosoft - * Copyright (C) 2021 Moritz Zwerger + * Copyright (C) 2020-2022 Moritz Zwerger * * This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. * @@ -15,12 +15,11 @@ package de.bixilon.minosoft.gui.rendering.modding.events.input import de.bixilon.minosoft.config.key.KeyCodes import de.bixilon.minosoft.gui.rendering.RenderWindow -import de.bixilon.minosoft.gui.rendering.Rendering import de.bixilon.minosoft.gui.rendering.modding.events.RenderEvent import de.bixilon.minosoft.gui.rendering.system.window.KeyChangeTypes class RawKeyInputEvent( - renderWindow: RenderWindow = Rendering.currentContext!!, + renderWindow: RenderWindow, val keyCode: KeyCodes, val keyChangeType: KeyChangeTypes, ) : RenderEvent(renderWindow) diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/system/window/GLFWWindow.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/system/window/GLFWWindow.kt index a5b0f731c..62b807d6e 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/system/window/GLFWWindow.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/system/window/GLFWWindow.kt @@ -20,10 +20,8 @@ import de.bixilon.kutil.os.PlatformInfo import de.bixilon.minosoft.config.key.KeyCodes import de.bixilon.minosoft.config.profile.profiles.rendering.RenderingProfile import de.bixilon.minosoft.gui.rendering.RenderWindow -import de.bixilon.minosoft.gui.rendering.modding.events.ResizeWindowEvent -import de.bixilon.minosoft.gui.rendering.modding.events.WindowCloseEvent -import de.bixilon.minosoft.gui.rendering.modding.events.WindowFocusChangeEvent -import de.bixilon.minosoft.gui.rendering.modding.events.WindowIconifyChangeEvent +import de.bixilon.minosoft.gui.rendering.Rendering +import de.bixilon.minosoft.gui.rendering.modding.events.* import de.bixilon.minosoft.gui.rendering.modding.events.input.MouseMoveEvent import de.bixilon.minosoft.gui.rendering.modding.events.input.MouseScrollEvent import de.bixilon.minosoft.gui.rendering.modding.events.input.RawCharInputEvent @@ -168,9 +166,6 @@ class GLFWWindow( } override fun init(profile: RenderingProfile) { - GLFWErrorCallback.createPrint(System.err).set() - check(glfwInit()) { "Unable to initialize GLFW" } - glfwDefaultWindowHints() if (renderWindow.preferQuads) { setOpenGLVersion(3, 0, false) @@ -215,12 +210,11 @@ class GLFWWindow( glfwFreeCallbacks(window) glfwDestroyWindow(window) - glfwTerminate() - glfwSetErrorCallback(null)!!.free() + glfwSetErrorCallback(null)?.free() } override fun close() { - if (eventMaster.fireEvent(WindowCloseEvent(window = this))) { + if (fireGLFWEvent(WindowCloseEvent(renderWindow, window = this))) { return } @@ -249,7 +243,7 @@ class GLFWWindow( return } - eventMaster.fireEvent(WindowFocusChangeEvent(window = this, focused = focused)) + fireGLFWEvent(WindowFocusChangeEvent(renderWindow, window = this, focused = focused)) } private fun onIconify(window: Long, iconified: Boolean) { @@ -257,14 +251,14 @@ class GLFWWindow( return } - eventMaster.fireEvent(WindowIconifyChangeEvent(window = this, iconified = iconified)) + fireGLFWEvent(WindowIconifyChangeEvent(renderWindow, window = this, iconified = iconified)) } private fun onClose(window: Long) { if (window != this.window) { return } - val cancelled = eventMaster.fireEvent(WindowCloseEvent(window = this)) + val cancelled = fireGLFWEvent(WindowCloseEvent(renderWindow, window = this)) if (cancelled) { glfwSetWindowShouldClose(window, false) @@ -277,7 +271,7 @@ class GLFWWindow( } val previousSize = Vec2i(_size) _size = Vec2i(width, height) - eventMaster.fireEvent(ResizeWindowEvent(previousSize = previousSize, size = _size)) + fireGLFWEvent(ResizeWindowEvent(renderWindow, previousSize = previousSize, size = _size)) this.skipNextMouseEvent = true } @@ -301,14 +295,14 @@ class GLFWWindow( } } - eventMaster.fireEvent(RawKeyInputEvent(keyCode = keyCode, keyChangeType = keyAction)) + fireGLFWEvent(RawKeyInputEvent(renderWindow, keyCode = keyCode, keyChangeType = keyAction)) } private fun charInput(windowId: Long, char: Int) { if (windowId != window) { return } - eventMaster.fireEvent(RawCharInputEvent(char = char)) + fireGLFWEvent(RawCharInputEvent(renderWindow, char = char)) } private fun mouseMove(windowId: Long, x: Double, y: Double) { @@ -322,7 +316,7 @@ class GLFWWindow( val delta = position - previous this.mousePosition = position if (!skipNextMouseEvent) { - eventMaster.fireEvent(MouseMoveEvent(position = position, previous = previous, delta = delta)) + fireGLFWEvent(MouseMoveEvent(renderWindow, position = position, previous = previous, delta = delta)) } else { skipNextMouseEvent = false } @@ -333,7 +327,7 @@ class GLFWWindow( return } - eventMaster.fireEvent(MouseScrollEvent(offset = Vec2d(xOffset, yOffset))) + fireGLFWEvent(MouseScrollEvent(renderWindow, offset = Vec2d(xOffset, yOffset))) } override fun setIcon(size: Vec2i, buffer: ByteBuffer) { @@ -348,7 +342,22 @@ class GLFWWindow( glfwSetWindowIcon(window, images) } + private fun fireGLFWEvent(event: RenderEvent): Boolean { + // ToDo: It looks like glfwPollEvents is mixing threads. This should not happen. + if (Rendering.currentContext != event.renderWindow) { + event.renderWindow.queue += { eventMaster.fireEvent(event) } + return false + } + return eventMaster.fireEvent(event) + } + companion object { + + init { + GLFWErrorCallback.createPrint(System.err).set() + check(glfwInit()) { "Unable to initialize GLFW" } + } + val KEY_CODE_MAPPING = mapOf( GLFW_KEY_UNKNOWN to KeyCodes.KEY_UNKNOWN, GLFW_KEY_SPACE to KeyCodes.KEY_SPACE, diff --git a/src/main/java/de/bixilon/minosoft/modding/event/master/EventMaster.kt b/src/main/java/de/bixilon/minosoft/modding/event/master/EventMaster.kt index b2af32b61..8b11a9270 100644 --- a/src/main/java/de/bixilon/minosoft/modding/event/master/EventMaster.kt +++ b/src/main/java/de/bixilon/minosoft/modding/event/master/EventMaster.kt @@ -13,9 +13,7 @@ package de.bixilon.minosoft.modding.event.master -import de.bixilon.kutil.collections.CollectionUtil.synchronizedSetOf import de.bixilon.kutil.collections.CollectionUtil.toSynchronizedList -import de.bixilon.kutil.collections.CollectionUtil.toSynchronizedSet import de.bixilon.kutil.concurrent.lock.simple.SimpleLock import de.bixilon.minosoft.modding.event.EventInstantFire import de.bixilon.minosoft.modding.event.events.CancelableEvent @@ -27,9 +25,10 @@ import java.util.* import kotlin.reflect.full.companionObjectInstance open class EventMaster(vararg parents: AbstractEventMaster) : AbstractEventMaster { - val parents: MutableSet = synchronizedSetOf(*parents) - private val eventInvokerLock = SimpleLock() + private val parents: MutableSet = mutableSetOf(*parents) + private val parentLock = SimpleLock() private val eventInvokers: PriorityQueue = PriorityQueue() + private val eventInvokerLock = SimpleLock() override val size: Int get() { @@ -42,9 +41,11 @@ open class EventMaster(vararg parents: AbstractEventMaster) : AbstractEventMaste override fun fireEvent(event: Event): Boolean { - for (parent in parents.toSynchronizedSet()) { + parentLock.acquire() + for (parent in parents) { parent.fireEvent(event) } + parentLock.release() val toRemove: MutableSet = mutableSetOf() eventInvokerLock.acquire()