Help With Signs

Discussion in 'Plugin Development' started by PandazNWafflez, Jun 8, 2012.

Thread Status:
Not open for further replies.
  1. Offline

    PandazNWafflez

    So, I've been doing some stuff with signs. I tried to cast BlockState to Sign, and got a ClassCastException. So instead I decided to cast Block to Sign. And I still got a ClassCastException.

    The weird thing is that the ClassCastException for BlockState said you can't cast BlockState to Sign, but for the Block -> Sign one, it didn't say you can't cast Block to Sign, it still said you can't cast BlockState to Sign... Which made no sense because I wasn't.

    Please help. If you need more code to know what's wrong, I can provide it.

    Full Stack Trace (the same for both): http://i.imgur.com/vIJkI.png Although I already know what it mean to some extent.
     
  2. Offline

    Acrobot

    Sign sign = (Sign) block.getState();

    And make sure that the block is a sign first:
    if (!(block.getState() instanceof Sign)) return;
     
  3. Offline

    PandazNWafflez

    That's what I did, but it still did it for some reason...
     
  4. Offline

    Giant

    Make sure you import the correct Sign!
    org.bukkit.block.Sign and not org.bukkit.materials.Sign
     
  5. as looking to his error, it cant be cast to an org.bukkit.block.Sign, so he imported the right class?
     
  6. Offline

    Giant

    Whoops missed that O__o...
     
  7. Offline

    lycano

    Hi, i just wanted to create a new thread about a similiar problem i have encountered. Maybe this would help you a bit and maybe someone who actually knows more about class casting than me can answer this more in detail.

    (TL;DR at end)

    WormholeXTreme did have this problem nearly the whole time and even the previous author didn't know why this happened and tried to counter this with replacing the sign by setting it to air first and then casting it to a WALL_SIGN (which would result in flicker and i don't like that).

    The logic is:
    * we have a gate that has a sign on a block to set the destination
    * each time a new gate is created all signs in the same network would have to be updated with the correct gatenames (obviously the order can change if you sort by name)
    * also when you remove a gate those signs have to be updated too
    * when you hit the sign the sign gets updated and shows the next target in the ringbuffer

    To do this i have a class named Stargate. I do store the block inside that class to use it as a reference point whenever i check for a sign or cycling through the ringbuffer.

    The code line would be something like this.setDialSign((Sign) getDialSignBlock().getState())

    More exactly: Stargate.java

    Nothing new to you but imagine the cases that may happen during Runtime.

    * The gate may be called twice from different threads, during that it may catch different states of the block
    * what happens if the other task finishes a tick earlier and runs again?

    Sometimes it will get Material.AIR because the minute a sign is checked during onEnable() i simply set it to air first then update it. This is done in a thread too and can collide during load with other threads. (I know this is all a bit messy and im working on a complete rewirte but actually i have to deal with whats there).

    Anyways the ClassCastException only happens during Runtime and not everytime so it has to do with setting the variable multiple times from different ticks. I played with it a bit and came to the same result as Acrobot

    That said i checked the contents if its anything else than a WALL_SIGN with

    if (!(getDialSignBlock().getType().equals(Material.WALL_SIGN)) { ... }

    (i guess his aproach is much cleaner as we just have to make sure its not a sign already)

    And only then set the sign cause i guess you can't cast the state of a sign multiple times in different threads as they may catch different states during runtime.

    TL;DR
    So maybe someone with more experience than me can explain in detail why this happens during runtime.
     
  8. Offline

    Acrobot

    lycano
    I'm unsure, however what I know is that messing with world data in threads is not a good idea.
    If I were you, I'd schedule the sign changing in a task, doing Bukkit.getScheduler().runTask(). It could limit the flickering to minimum.
     
  9. Offline

    lycano

    Acrobot: well i dont have any flicker when interacting only when recreating the sign cause i set it to AIR and then change it to a WALL_SIGN. I agree on the threading part when it comes to "why the error is happening" but what i would like to know is "why exactly" ^.^
     
Thread Status:
Not open for further replies.

Share This Page