Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Am I abusing static?

Tags:

java

bukkit

To disguise players as another Entity, I made a disguise class as you can see here:

public class Disguise
{
    private static HashSet<Disguise> disguises = new HashSet<>();
    private net.minecraft.server.v1_8_R2.EntityLiving nmsEntity;
    private Player disguise;

    public Disguise(Player disguise, EntityLiving entity, boolean affectLogin)
    {
        if(affectLogin)
            disguises.add(this);

        this.disguise = disguise;
        this.nmsEntity = entity;
    }

    public Disguise(Player disguise, EntityLiving entity)
    {
        this(disguise, entity, true);
    }

    public void send(Player visible)
    {
        if(visible == disguise)
            return;

        EntityPlayer player = NMSUtils.getNMSPlayer(visible);

        nmsEntity.setPosition(player.locX, player.locY, player.locZ);
        nmsEntity.d(disguise.getEntityId());
        nmsEntity.setCustomName(disguise.getDisplayName());
        nmsEntity.setCustomNameVisible(true);

        PacketPlayOutSpawnEntityLiving spawn = new PacketPlayOutSpawnEntityLiving(nmsEntity);
        PacketPlayOutEntityDestroy destroy = new PacketPlayOutEntityDestroy(disguise.getEntityId());

        player.playerConnection.sendPacket(destroy);
        player.playerConnection.sendPacket(spawn);
    }

    public void send(List<Player> visible)
    {
        for(Player player : visible)
            send(player);
    }

    public void send(Player... visible)
    {
        send(Arrays.asList(visible));
    }

    public void send()
    {
        send(new ArrayList<>(Bukkit.getOnlinePlayers()));
    }

    public Player getDisguised()
    {
        return disguise;
    }

    public static HashSet<Disguise> getDisguises()
    {
        return disguises;
    }
}

I also have a static HashSet which stores all the instances made. I am doing this because I want players who login to see the disguise aswell and I want to remove the disguise from the player when the player logs out. Is a static HashSet the way to do it (like I'm doing it)? And if not, how should it be done?

like image 224
XLordalX Avatar asked May 18 '15 15:05

XLordalX


2 Answers

static was asking for it. By its nature, it is prone to "abuse", but that's just part of the challenge.

When all is said and done, if your mod does what you need it to do without bugginess, don't stress too much about best practices at this level of granularity (a particular variable). It's not likely to ever scale in scope to the point where poor design would cause problems for you. It's not a life-support system, after all.

If you want to practice good form for fun, my first instinct would be to move your management logic from Disguise to a (e.g.) DisguiseManager class, and handle all Disguise creation/destruction through a manager class. Less complex would be private constructor and static create/destroy methods on Disguise. Global side-effects in constructors like you posted is generally bad form.

like image 148
Cheezmeister Avatar answered Nov 06 '22 09:11

Cheezmeister


Basically everytime a constructor is called, you want to add this to a global place.

That's fine, but there are two concerns:

  1. exposing this in constructor is dangerous and requires careful analysis. (your code is buggy in this aspect)
  2. concurrency - if the app is multi-threaded, it needs to be thread-safe. (exposing this in constructor is more problematic in a concurrent environment)
  3. garbage collection - when the object becomes "garbage", how to remove it from the global place.
like image 24
ZhongYu Avatar answered Nov 06 '22 09:11

ZhongYu