mirror of
https://github.com/MightyPirates/OpenComputers.git
synced 2025-09-14 09:46:53 -04:00
refactored screen env into screen's companion object (same as already done with computer); keeping track of pressed keys client-side to send char on key-up (lwjgl doesn't seem to properly provide that, code and char always seem to be 0 on key up) and to send key up events for all still pressed keys when closing the gui. server will have to keep track of all key presses (and the players that did them) at some point, too, since clients may just disconnect, for example (or be malicious)
This commit is contained in:
parent
deb45f374f
commit
cbfbc2f152
@ -33,7 +33,7 @@ function component.primary(componentType, ...)
|
||||
end
|
||||
else
|
||||
assert(component.isAvailable(componentType),
|
||||
"no primary " .. componentType .. " available")
|
||||
"no primary '" .. componentType .. "' available")
|
||||
return primaries[componentType]
|
||||
end
|
||||
end
|
||||
|
@ -10,6 +10,7 @@ import net.minecraft.client.renderer.texture.TextureManager
|
||||
import net.minecraft.util.ResourceLocation
|
||||
import org.lwjgl.input.Keyboard
|
||||
import org.lwjgl.opengl.GL11
|
||||
import scala.collection.mutable
|
||||
|
||||
/**
|
||||
* This GUI shows the buffer of a single screen.
|
||||
@ -25,7 +26,9 @@ import org.lwjgl.opengl.GL11
|
||||
class Screen(val tileEntity: tileentity.Screen) extends MCGuiScreen {
|
||||
tileEntity.guiScreen = Some(this)
|
||||
|
||||
var (x, y, innerWidth, innerHeight, scale) = (0, 0, 0, 0, 0.0)
|
||||
private var (x, y, innerWidth, innerHeight, scale) = (0, 0, 0, 0, 0.0)
|
||||
|
||||
private val pressedKeys = mutable.Map.empty[Int, Char]
|
||||
|
||||
/** Must be called when the size of the underlying screen changes */
|
||||
def setSize(w: Double, h: Double) = {
|
||||
@ -53,18 +56,19 @@ class Screen(val tileEntity: tileentity.Screen) extends MCGuiScreen {
|
||||
super.handleKeyboardInput()
|
||||
|
||||
val code = Keyboard.getEventKey
|
||||
val char = Keyboard.getEventCharacter
|
||||
|
||||
if (code != Keyboard.KEY_ESCAPE && code != Keyboard.KEY_F11)
|
||||
if (code == Keyboard.KEY_INSERT && MCGuiScreen.isShiftKeyDown) {
|
||||
if (Keyboard.getEventKeyState)
|
||||
PacketSender.sendClipboard(tileEntity, MCGuiScreen.getClipboardString)
|
||||
}
|
||||
else if (Keyboard.getEventKeyState) {
|
||||
val char = Keyboard.getEventCharacter
|
||||
PacketSender.sendKeyDown(tileEntity, char, code)
|
||||
pressedKeys += code -> char
|
||||
}
|
||||
else {
|
||||
PacketSender.sendKeyUp(tileEntity, char, code)
|
||||
else pressedKeys.remove(code) match {
|
||||
case Some(char) => PacketSender.sendKeyUp(tileEntity, char, code)
|
||||
case _ => // Wasn't pressed while viewing the screen.
|
||||
}
|
||||
}
|
||||
|
||||
@ -85,6 +89,9 @@ class Screen(val tileEntity: tileentity.Screen) extends MCGuiScreen {
|
||||
override def onGuiClosed() = {
|
||||
super.onGuiClosed()
|
||||
tileEntity.guiScreen = None
|
||||
for ((code, char) <- pressedKeys) {
|
||||
PacketSender.sendKeyUp(tileEntity, char, code)
|
||||
}
|
||||
}
|
||||
|
||||
override def drawScreen(mouseX: Int, mouseY: Int, dt: Float): Unit = {
|
||||
|
@ -1,13 +1,16 @@
|
||||
package li.cil.oc.common.component
|
||||
|
||||
import li.cil.oc.api.network.{Message, Visibility, Node}
|
||||
import li.cil.oc.util.TextBuffer
|
||||
import net.minecraft.nbt.NBTTagCompound
|
||||
|
||||
class Screen(val owner: ScreenEnvironment) {
|
||||
class Screen(val owner: Screen.Environment) {
|
||||
val supportedResolutions = List((40, 24), (80, 24))
|
||||
|
||||
private val buffer = new TextBuffer(80, 24)
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
|
||||
def text = buffer.toString
|
||||
|
||||
def lines = buffer.buffer
|
||||
@ -40,6 +43,8 @@ class Screen(val owner: ScreenEnvironment) {
|
||||
if (buffer.copy(col, row, w, h, tx, ty))
|
||||
owner.onScreenCopy(col, row, w, h, tx, ty)
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
|
||||
def load(nbt: NBTTagCompound) = {
|
||||
buffer.readFromNBT(nbt.getCompoundTag("buffer"))
|
||||
}
|
||||
@ -49,4 +54,64 @@ class Screen(val owner: ScreenEnvironment) {
|
||||
buffer.writeToNBT(nbtBuffer)
|
||||
nbt.setCompoundTag("buffer", nbtBuffer)
|
||||
}
|
||||
}
|
||||
|
||||
object Screen {
|
||||
|
||||
trait Environment extends Node {
|
||||
final val screen = new Screen(this)
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
|
||||
override val name = "screen"
|
||||
|
||||
override val visibility = Visibility.Network
|
||||
|
||||
override def receive(message: Message): Option[Array[Any]] = super.receive(message).orElse {
|
||||
message.data match {
|
||||
case Array(w: Int, h: Int) if message.name == "screen.resolution=" =>
|
||||
result(screen.resolution = (w, h))
|
||||
case Array() if message.name == "screen.resolution" => {
|
||||
val (w, h) = screen.resolution
|
||||
result(w, h)
|
||||
}
|
||||
case Array() if message.name == "screen.resolutions" =>
|
||||
result(screen.supportedResolutions: _*)
|
||||
case Array(x: Int, y: Int, value: String) if message.name == "screen.set" =>
|
||||
screen.set(x, y, value); None
|
||||
case Array(x: Int, y: Int, w: Int, h: Int, value: Char) if message.name == "screen.fill" =>
|
||||
screen.fill(x, y, w, h, value); None
|
||||
case Array(x: Int, y: Int, w: Int, h: Int, tx: Int, ty: Int) if message.name == "screen.copy" =>
|
||||
screen.copy(x, y, w, h, tx, ty); None
|
||||
case _ => None
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
|
||||
override def load(nbt: NBTTagCompound) = {
|
||||
super.load(nbt)
|
||||
screen.load(nbt.getCompoundTag("screen"))
|
||||
}
|
||||
|
||||
override def save(nbt: NBTTagCompound) = {
|
||||
super.save(nbt)
|
||||
|
||||
val screenNbt = new NBTTagCompound
|
||||
screen.save(screenNbt)
|
||||
nbt.setCompoundTag("screen", screenNbt)
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
|
||||
def onScreenResolutionChange(w: Int, h: Int) =
|
||||
network.foreach(_.sendToVisible(this, "computer.signal", "screen_resized", w, h))
|
||||
|
||||
def onScreenSet(col: Int, row: Int, s: String) {}
|
||||
|
||||
def onScreenFill(col: Int, row: Int, w: Int, h: Int, c: Char) {}
|
||||
|
||||
def onScreenCopy(col: Int, row: Int, w: Int, h: Int, tx: Int, ty: Int) {}
|
||||
}
|
||||
|
||||
}
|
@ -1,62 +0,0 @@
|
||||
package li.cil.oc.common.component
|
||||
|
||||
import li.cil.oc.api.network.{Node, Visibility, Message}
|
||||
import net.minecraft.nbt.NBTTagCompound
|
||||
|
||||
/**
|
||||
* Environment for screen components.
|
||||
*
|
||||
* The environment of a screen is responsible for synchronizing the component
|
||||
* between server and client. These callbacks are only called on the server
|
||||
* side to trigger changes being sent to clients and saving the current state.
|
||||
*/
|
||||
trait ScreenEnvironment extends Node {
|
||||
val screen = new Screen(this)
|
||||
|
||||
override val name = "screen"
|
||||
|
||||
override val visibility = Visibility.Network
|
||||
|
||||
override def receive(message: Message): Option[Array[Any]] = super.receive(message).orElse {
|
||||
message.data match {
|
||||
case Array(w: Int, h: Int) if message.name == "screen.resolution=" =>
|
||||
result(screen.resolution = (w, h))
|
||||
case Array() if message.name == "screen.resolution" => {
|
||||
val (w, h) = screen.resolution
|
||||
result(w, h)
|
||||
}
|
||||
case Array() if message.name == "screen.resolutions" =>
|
||||
result(screen.supportedResolutions: _*)
|
||||
case Array(x: Int, y: Int, value: String) if message.name == "screen.set" =>
|
||||
screen.set(x, y, value); None
|
||||
case Array(x: Int, y: Int, w: Int, h: Int, value: Char) if message.name == "screen.fill" =>
|
||||
screen.fill(x, y, w, h, value); None
|
||||
case Array(x: Int, y: Int, w: Int, h: Int, tx: Int, ty: Int) if message.name == "screen.copy" =>
|
||||
screen.copy(x, y, w, h, tx, ty); None
|
||||
case _ => None
|
||||
}
|
||||
}
|
||||
|
||||
override def load(nbt: NBTTagCompound) = {
|
||||
super.load(nbt)
|
||||
screen.load(nbt.getCompoundTag("screen"))
|
||||
}
|
||||
|
||||
override def save(nbt: NBTTagCompound) = {
|
||||
super.save(nbt)
|
||||
|
||||
val screenNbt = new NBTTagCompound
|
||||
screen.save(screenNbt)
|
||||
nbt.setCompoundTag("screen", screenNbt)
|
||||
|
||||
}
|
||||
|
||||
def onScreenResolutionChange(w: Int, h: Int) =
|
||||
network.foreach(_.sendToVisible(this, "computer.signal", "screen_resized", w, h))
|
||||
|
||||
def onScreenSet(col: Int, row: Int, s: String) {}
|
||||
|
||||
def onScreenFill(col: Int, row: Int, w: Int, h: Int, c: Char) {}
|
||||
|
||||
def onScreenCopy(col: Int, row: Int, w: Int, h: Int, tx: Int, ty: Int) {}
|
||||
}
|
@ -3,16 +3,23 @@ package li.cil.oc.common.tileentity
|
||||
import li.cil.oc.api.network.PoweredNode
|
||||
import li.cil.oc.client.gui
|
||||
import li.cil.oc.client.{PacketSender => ClientPacketSender}
|
||||
import li.cil.oc.common.component.ScreenEnvironment
|
||||
import li.cil.oc.common.component
|
||||
import li.cil.oc.server.{PacketSender => ServerPacketSender}
|
||||
import net.minecraft.nbt.NBTTagCompound
|
||||
|
||||
class Screen extends Rotatable with ScreenEnvironment with PoweredNode {
|
||||
class Screen extends Rotatable with component.Screen.Environment with PoweredNode {
|
||||
var guiScreen: Option[gui.Screen] = None
|
||||
|
||||
/** Read and reset to false from the tile entity renderer. */
|
||||
/**
|
||||
* Read and reset to false from the tile entity renderer. This is used to
|
||||
* keep rendering a little more efficient by compiling the displayed text
|
||||
* into an OpenGL display list, and only re-compiling that list when the
|
||||
* text/display has actually changed.
|
||||
*/
|
||||
var hasChanged = false
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
|
||||
override def readFromNBT(nbt: NBTTagCompound) = {
|
||||
super.readFromNBT(nbt)
|
||||
load(nbt.getCompoundTag("node"))
|
||||
@ -32,8 +39,6 @@ class Screen extends Rotatable with ScreenEnvironment with PoweredNode {
|
||||
ClientPacketSender.sendScreenBufferRequest(this)
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
// IScreenEnvironment
|
||||
// ----------------------------------------------------------------------- //
|
||||
|
||||
override def onScreenResolutionChange(w: Int, h: Int) = {
|
||||
|
@ -1,7 +1,7 @@
|
||||
package li.cil.oc.server.component
|
||||
|
||||
import li.cil.oc.api.network.{Node, Visibility, Message}
|
||||
import li.cil.oc.common.component.ScreenEnvironment
|
||||
import li.cil.oc.common.component
|
||||
import net.minecraft.nbt.NBTTagCompound
|
||||
|
||||
class GraphicsCard extends Node {
|
||||
@ -21,7 +21,7 @@ class GraphicsCard extends Node {
|
||||
network.fold(None: Option[Array[Any]])(network => {
|
||||
network.node(new String(address, "UTF-8")) match {
|
||||
case None => result(Unit, "invalid address")
|
||||
case Some(node: ScreenEnvironment) =>
|
||||
case Some(node: component.Screen.Environment) =>
|
||||
screen = node.address
|
||||
result(true)
|
||||
case _ => result(Unit, "not a screen")
|
||||
|
Loading…
x
Reference in New Issue
Block a user