CC: Tweaked

CC: Tweaked

42M Downloads

API: Add methods to IWiredElement to check if it's a modem and if it has peripherals

caelwarner opened this issue ยท 2 comments

commented

Hello

I need a way for peripherals to know if they are currently connected to a modem. This is useful for enabling/disabling certain functionality on a block entity if it's connected to a modem. I see that I can use IPeripheral#attach and IPeripheral#detach to monitor computers connecting and disconnecting from the network, but to use this effectively I'd have to store the amount of attached computers and increment/decrement the amount whenever a computer joins/leaves the network. It works but it's a heavy implementation, especially if the client needs to be aware of these changes.

I've seen ComputerCraftAPI#getWiredElementAt and it looks helpful. However, there isn't much I can currently do with a IWiredElement. I propose adding a couple of methods to IWiredElement to check if it's a modem and if it has connected peripherals. The methods could look something like boolean isModem() and boolean hasConnectedPeripherals().

Thanks!

commented

Going through Creators-of-Create/Create#3880, and I don't think this is the correct solution to your problem. IWiredElement is the wrong interface to be targeting here, as you also need to account for the computer accing the peripheral directly.

I think the correct thing to do here is to use IPeripheral.attach and IPeripheral.detach. It doesn't need to be heavyweight - you can just use an AtomicInteger to count the number of computers, so something like:

class PeripheralBase ... {
  private final AtomicInteger computers = new AtomicInteger();
  @Override public void attach(IComputerAccess computer) { computers.incrementAndGet(); }
  @Override public void detach(IComputerAccess computer) { computers.decrementAndGet(); }
  public boolean isAttached() { return computers.get() > 0; }
}

And then use that inside ComputerControllable:

interface ComputerControllable {
  LazyOptional<PeripheralBase<?>> getPeripheral();
  default boolean isComputerControlled() {
    var peripheral = getPeripheral();
    return peripheral != null && peripheral.isPresent() && peripheral.orElseThrow(NullPointerException::new).isAttached();
  }
}

I was going to suggest using ContainerData for syncing isComputerControlled to the client, but it looks like Create doesn't even use Menu for its GUIs? Ahhhhhh! Why!?!?!?

commented

Thanks for your reply. I had completely forgotten that computers can directly access peripherals. I think I will have to go the way of using IPeripheral#attach and IPeripheral#detach. I will just have to write my own packet to sync with the client. Thanks again!