Computers now use a MainThreadScheduler to construct a
MainThreadScheduler.Executor, which is used to submit tasks. Our
previous (singleton) MainThread and MainThreadExecutor now implement
these interfaces.
The main purpose of this is to better manage the lifetime of the server
thread tasks. We've had at least one bug caused by us failing to reset
its state, so good to avoid those! This also allows us to use a fake
implementation in tests where we don't expect main thread tasks to run.
As we're now passing a bunch of arguments into our Computer, we bundle
the "global" ones into ComputerContext (which now also includes the Lua
machine factory!). This definitely isn't the nicest API, so we might
want to rethink this one day.
In some ways this isn't as nice as the Forge version (requires ATs,
doesn't check texture/model existence). However, it's more multi-loader
friendly and in some cases has much less boilerplate.
Blockstate JSON files are incredibly verbose, so we add a custom JSON
pretty printer which writes things in a slightly more compact manner.
This also changes how turtle upgrades are loaded - we now support
standard ResourceLocations (so computercraft:blocks/some_turtle_upgrade)
as well as ModelResourceLocations (computercraft:items/some_turtle_upgrade#inventory).
I don't think any resource packs need to touch our upgrades, but
apologies if this breaks anything.
- Convert remaining recipes over to datagen.
- Switch loot tables to use vanilla's loot table generator. It's
honestly not too different, just the earlier system confused me too
much :).
Alas, a positive diff because the JSON is so verbose. I've got a really
nice patch which makes the JSON more compact, but alas the Mixin doesn't
apply on 1.16 :(.
- Remove TrackingField and replace it with a Metric abstract class.
This has two concrete subclasses - Counter and Event. Events carry an
additional piece of data each time it is observed, such as HTTP
response size.
- Computers now accept a MetricsObserver, which tracks metrics for this
particular computer. This allows us to decouple Computer classes and
metrics information. The concrete MetricsObserver class we use within
Minecraft exposes the ServerComputer directly, so we no longer need to
do the awkward mapping and lookups!
- The /computercraft command can now do aggregates (count, avg, max)
over all Event metrics. This removes the need for special handling of
computer and server time.
There's also a small number of changes in removing the coupling between
Computer and some of its dependencies (ILuaMachine, MainThreadExecutor).
This makes some future refactorings easier, I promise!
This is a little odd (it's more complex for one!), but means we can
reuse the internal API interface in other classes, which is useful for
the data provider refactor I'm about to do.
This is much nicer in Java 17 :D (records, ServiceLoader.stream()),
but such is the perils of still targetting 1.16.
We now fuzz UploadFileMessage, generating random files and checking they
round-trip correctly.
The joy of having a long-lasting refactor branch with an absolutely
massive diff, is that you end up spotting bugs, and then it's a massive
pain to merge the fix back into trunk!
The last 4 or 5 commits have simplified things. I can now have some
unnecessary complexity as a treat!
This is some initial work on better tying the lifecycle of
computers (and ComputerCraft) related state to the lifecycle of the
current Minecraft server.
- Move server-wide methods in IComputerEnvironment (such as creating
resource mounts) into a separate interface.
- Add a new ServerContext class, which now holds the ID Assigner,
server computer registry, and some other tiny bits and bobs. This can
only be accessed by ServerContect.get(MinecraftServer), forcing
slightly better discipline for how we use these globals.
This does allow us to nuke some of the ugliest bits in IDAssigner. Even
if it makes things much longer!
Moves ID assigning out of the Computer class and into wherever we
construct the ServerComputer (so in computer blocks and pocket computer
items).
This is definitely not perfect - it'd be nice to make ServerComputers
more responsible for managing the lifecycle of computers (so assigning
ids, handling auto-starting, etc...), but I've not found a good way to
handle this yet!
They bring very little to the table now that computers do their own
thing! This also helps simplify the code in ServerMonitor a bit - turns
out we had two "dirty" flags in the implementation!
Previously we stored it alongside the terminal. While this makes sense -
it's not a property of the terminal itself, it ends up duplicating code
in a bunch of places.
We now track the colour flag on the terminal itself. This allows us to
simplify a couple of things:
- The palette now also knows whether it supports colours or not, and so
performs greyscale conversion. This means we no longer need to thread
a "greyscale" flag throughout terminal rendering.
- Remove isColour() getters from a whole load of
places (TerminalMethods, ServerTerminal, IComputerEnvironment).
Historically CC has maintained two computer registries; one on the
server (which runs the actual computer) and one on the client (which
stores the terminal and some small bits of additional data).
This means when a user opens the computer UI, we send the terminal
contents and store it in the client computer registry. We then send the
instance id alongside the "open container" packet, which is used to look
up the client computer (and thus terminal) in our client-side registry.
This patch makes the computer menu syncing behaviour more consistent
with vanilla. The initial terminal contents is sent alongside the "open
container" packet, and subsequent terminal changes apply /just/ to the
open container. Computer on/off state is synced via a vanilla
ContainerData/IIntArray.
Likewise, sending user input to the server now targets the open
container, rather than an arbitrary instance id.
The one remaining usage of ClientComputer is for pocket computers. For
these, we still need to sync the current on/off/blinking state and the
pocket computer light.
We don't need the full ClientComputer interface for this case (after
all, you can't send input to a pocket computer someone else is
holding!). This means we can tear out ClientComputer and
ClientComputerRegistry, replacing it with a much simpler
ClientPocketComputers store.
This in turn allows the following changes:
- Remove IComputer, as we no longer need to abstract over client and
server computers.
- Likewise, we can merge ComputerRegistry into the server
registry. This commit also cleans up the handling of instance IDs a
little bit: ServerComputers are now responsible for generating their
ID and adding/removing themselves from the registry.
- As the client-side terminal will never be null, we can remove a whole
bunch of null checks throughout the codebase.
- As the terminal is available immediately, we don't need to explicitly
pass in terminal sizes to the computer GUIs. This means we're no
longer reliant on those config values on the client side!
- Remove the "request computer state" packet. Pocket computers now
store which players need to know the computer state, automatically
sending data when a new player starts tracking the computer.
Caused by 4228011b84. While correct on
1.18, this isn't correct on 1.19 - I clearly messed up the merge here.
Fixes#1183, possibly #1184 - haven't been able to reproduce.
I was going to do something productive tonight, but then this happened.
Whatever, I'm retired, I'm allowed to make my entire existence just
adding 50px to things. Heck, maybe I'll do the same tomorrow too.
Closes#1133. I'm not super happy about any of the versions proposed
there, but I think this is better than nothing.
Co-authored-by: JackMacWindows <jackmacwindowslinux@gmail.com>
We clamped various values to the height of the screen, rather than the
height of the content box (height-1). We didn't notice this most of the
time as the last line of a file is empty - it only really mattered when
a file was the same height as the computer's screen.
We now do the following:
- Strip the trailing new line from a file when reading.
- Replace most usages of height with height-1.
Previously illumainate required manual users to manually download it and
place it in ./bin/. This is both inconvenient for the user, and makes it
hard to ensure people are running the "right" version.
We now provide a small Gradle plugin which registers illuaminate as a
ependency, downloading the appropriate (now versioned!) file. This also
theoretically supports Macs, though I don't have access to one to test
this.
This enables the following changes:
- The Lua lint script has been converted to a Gradle task (./gradle
lintLua).
- illuaminateDocs now uses a task definition with an explicit output
directory. We can now consume this output as an input to another
task, and get a task dependency implicitly.
- Move the pre-commit config into the root of the tree. We can now use
the default GitHub action to run our hooks.
- Simplify CONTRIBUTING.md a little bit. Hopefully it's less
intimidating now.
This is mostly copied from the work Toad and I did for CC:R.
Instead of not writing to the depth buffer when rendering terminals, we
now render terminal forgrounds with a small glPolygonOffset (or an
emulation of it where not possible). This removes the need for custom
render types, while still avoiding z-fighting between the terminal
foreground and background.
The VBO monitors backend now uses Iris's TextVertexSink API when
available: Iris overwrites the vertex format for RenderType.text, and so
we need to use this API to avoid rendering garbage.
Performance is maybe a little worse than before (<3ms) and definitely
worse than CC:R. Unfortunately we can't do our upload batching as that
conflicts with Optifine's patches - instead we need to maintain two
separate VBOs. This is a bit slower, but not so bad it's unworkable.
ITurtleUpgrade.getModel has always been rather error-prone to use, due
to its client-only nature. As ModelResourceLocation is now client-only
again in Forge 1.19.1, no seems a good time to fix this.
The getter for models is now a separate interface inside a new
dan200.computercraft.api.client package. These are registered
per-TurtleUpgradeSerialiser (as those should correspond to class
anyway). It's a little ugly, and we may rename the XxxSerialiser classes
to something more general in a future update.
I'm not wild about the interface here either - happy to change it in
future versions too.
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Also clean up the generic arguments to IUpgradeBase/UpgradeSerialiser a
little bit. It's not great (wish Java had HKTs), but it's better.