CC: Tweaked

CC: Tweaked

42M Downloads

Turtle able to desync peripheral

MakerTim opened this issue · 5 comments

commented

Useful information to include:

  • Minecraft version 1.16.4
  • CC: Tweaked version 1.95.1
  • Logs: (no bugs related, but here they are)
    debug.log
    latest.log

image
Steps to reproduce:
place a turtle, any will work
place a peripheral (as a block) left to it

LUA:

x = peripheral.wrap("left")
x.has_nbt() -- method that peripheral has, in my case an observer from nbt_peripherals //returns true
turtle.turnLeft() -- true
x.has_nbt() -- same method as before, now states that this method no longer exists
x.has_nbt -- it still thinks it has a reference to the function

image

expected that whole x should be nil or that the function still works... now the turtle is in a broken state

commented

There's two interpretations of what "wrapping a peripheral" should do.

  • Return a view of that peripheral slot, dynamically adding/removing methods as the peripheral changes.
  • Returning a static view of the peripheral at that point.

Obviously both interpretations of this are perfectly fine, it's just peripheral.wrap chooses to go for the second of these. I think generally this is the correct choice - you're mostly interested of peripherals of a specific type rather than in a specific location.

As far as detecting whether a peripheral is still there, there's a couple of options:

  • Listen to peripheral_detach events and handle them appropriately.
  • Call peripheral.getType/peripheral.isPresent before using the peripheral.
  • Roll your own wrapper which behaves as described in the first bullet point above.
commented
commented

This is expected. When the turtle turns left the peripheral is is no longer on the left, but in front of the turtle instead. And so the reference to "left" is no longer accurate - you'd need to wrap "front" instead.

Similar issues arise if you just wrap a peripheral on one side and break it. The table returned by peripheral.wrap sticks around (because why wouldn't it), and there's not really an easy way to clear it.

commented

Yeah that is true but then x (variable the wrap is in) should not have a reference to the methods anymore since its not in that orientation which it now does.

Only when you try to execute it it will say it doesnt have a ref anymore, while if you read x it stil lshows the refs to the methods.

commented

I expected the peripheral to be broken, as expected
but the object of the peripheral is still an object and the references to the methods are still references to the method
shouldn't the type of or the functions or the wrap be nil when? now you cannot detect in code that it's broken