[Util] Cuboids API

Discussion in 'Resources' started by JBoss925, Jul 16, 2014.

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


    Welcome to the thread. I've created this thread to allow access to my CuboidsAPI. A cuboid is a 3D region very similar to that of the regions created with 2 positions in World Edit. The reason I've created this API is the fact that I've seen people doing some very wrong practices as well as some confusion in doing the correct practices. Some examples include, people creating objects similar to my cuboid object by storing all the blocks in a 3D region rather than the mins and maxes of the different coordinate types and people trying to use the world edit api without using documentation.​
    As you may be able to tell, I switched everything to github, there's a wiki and the source as well as tutorials and more over there to help you if you need it:D.​
    This is the simplest part.​
    You can use this as a Util by:
    1. Copying and pasting the code from here into a class in your IDE.
    For Use
    In order to use ConfigurationSerializable you must register the Util's class. I recommend copying the code from here rather than the CuboidsAPIWiki's Serialization Setup section since the code's a bit messed up on the wiki but see the Serialization Setup section for written instructions on how to register the class. Then find the tutorial for Serialization here.

    Find the source on GitHub here.
    Find documentation here.

    Find the wiki here for more on Serialization Setup, Serialization Tutorial, Installation, Documentation, and Changelogs.

    Edited 23 times lol vvvv​
    ChipDev, MnMaxon, Plugers11 and 2 others like this.
  2. Offline


    JBoss925 A few things:
    - The "iterator", it isn't much an iterator at all (where iterator is an implementation of Iterator). You could do a few things for this, like ditch the "CuboidIterator" entirely and just have Cuboid implement Iterable<Block>. edit: Implementing Iterable allows them to directly iterate through the Cuboid (such as a for-each loop)
    - The Serialization, what is this intended for? If you plan on saving this to a configuration file, simply implement ConfigurationSerializable and its requisites (de/serialize and registering), thus removing that class as well.
    - Your Cuboid's constructor (Location, Location) is comparing Strings with ==, may have unintended results.
    - Your checks for the min's/max's could probably be more efficient using elses, as there are only 2 of each (2 x's, 2 y's, 2 z's)
    Some pointers:
    - Checking if a Player is in the Cuboid is as simple as checking if they are in the same world and in between the min x, y, and z's.
    - Perhaps a function to determine if a Block is located in the cuboid?
    - Take the first two tips I gave, and you can turn this into one class, removing the need for a jar dependency, and creating thus creating a "Util" rather then a "Lib".
    That aside, the effort to try and reduce the "bad practices" of others is appreciated, and some of the things I have posted may be opinion-based. Feel free to take my suggestions and modify them to your liking.
  3. Offline


    I actually thought about the ConfigurationSerialization but I thought that some beginner programmers may have trouble with it. Other than that I completely forgot about implementing Iterable and I'm going to go ahead and get working on this. Also the block idea is good and I'll go ahead and try to shrink this into a Util.
  4. Offline


    JBoss925 Beginner "programmers" should take the time to learn about it if they plan on storing their own data structures in a config rather then having one long String of each element appended together using something like :: or *. ConfigurationSerializable is a useful thing, and you should use it rather then giving them the idea of concating massive amounts of data together (what if they were to make an undefined shape that has a varied amount of points, would be smarter to do something like an Array that is serialized (Bukkit's Vector is serializable) rather then "point1x-point1y::pointnx-pointny::etc".
    Point being, if you are worried about beginner programmers getting confused, then don't worry. I'd think that you would rather have a confused person asking about ConfigurationSerializable then someone concat-ing 1000 points for serialization.

    Tip: Perhaps a section to explain ConfigurationSerializable or a link to something explaining it along with stating that knowing how it works is recommended.
  5. Offline


    That's a great idea. I'll add ConfigurationSerializable.
  6. Offline


    In the part that you check for the max and min locations, why don't you do something like this?
    2. double max_x, max_y, max_z, min_x, min_y, min_z;
    3. max_x = Math.max(l1.getX(), l2.getX());
    4. max_y = Math.max(l1.getY(), l2.getY());
    5. max_z = Math.max(l1.getZ(), l2.getZ());
    6. min_x = Math.min(l1.getX(), l2.getX());
    7. min_y = Math.min(l1.getY(), l2.getY());
    8. min_z = Math.min(l1.getZ(), l2.getZ());

    (I wrote it in my cellphone, sorry of I did something wrong)
  7. Offline


    Interesting. I've made "cuboids" (objects) before with some trickery but they weren't actually cuboids at all.
    I dislike using things like worledit because I have to test and use math to find the 2 positions.
    You should add methods to get the cuboid of the player if this is really an "API"
  8. Offline


    Cuboid of the player? Are you saying to link players and cuboids? And thanks!
  9. Offline


    LordVakar JBoss925
    I think that he means the axis aligned bounding box (AABB).
    1. Player player = null;
    2. AxisAlignedBB axisAlignedBB = ((CraftPlayer) player).getHandle().boundingBox;

    You can get the min values now from: axisAlignedBB.a, axisAlignedBB.b, axisAlignedBB.
    and the max values from: axisAlignedBB.d, axisAlignedBB.e, axisAlignedBB.f
  10. Offline


    Ohh sure. I can very easily implement this.
  11. Offline


    JBoss925 why dont u use Math.min Math.max?
  12. Offline


    It does the exact same thing and would take longer to call the method from the JDK.
  13. Offline


    JBoss925 It takes no longer then your method. Should either use Math#min()/max() or mimic its code, it is more legible and just looks cleaner (which can sometimes help others understand it better then a wall of text)
  14. I don't understand why use all this code, simple class that can be shortened a lot more and in my opinion is neater:
    I use my own modified version of desht 's Cuboid class that I will paste when I get home from work, which includes block iteration and doesn't have the NMS which makes everything more complicated. Once you remove the unwanted methods, the NMS especially, it becomes so simple, neat and short.
  15. Offline


    The link includes multiple classes and many similar methods. Also, I'm working on shortening this into a single class (util) by implementing Iterator<Block> and trying to use ConfigurationSerializable.
    KingFaris11 likes this.
  16. Offline


    It's true that my Cuboid class has a lot of cruft that doesn't really need to be in a more general cuboid implementation; when I wrote it originally, it was only for use in ChessCraft. I've been meaning to clean it up for quite some time but never got round to it, and KingFaris11 has since published a simplified version of the class elsewhere. A minimal (and probably mutable, like Location or Vector) Cuboid class would be a fine candidate for inclusion in Bukkit.

    However, I think you may be confused about the difference between the Iterable and Iterator interfaces. Making Cuboid implement Iterator<Block> directly doesn't make sense; a Cuboid isn't an iterator. But it does make sense to make it implement Iterable<Block> - then you can say for (Block b : myCuboid) { ... }. The point being, you'll need a separate CuboidIterator class to handle the actual iteration. Further reading: http://stackoverflow.com/questions/5836174/java-iterator-and-iterable
    KingFaris11 likes this.
  17. Offline


    I'm very sorry for the confusion. I meant Iterable<Block>. My apologies.

    xTigerRebornx KingFaris11 Ok, I've taken your advice and I've managed to condense it into 1 class. I've also created a serialization section to help those new to ConfigurationSerializable.

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
    Last edited by a moderator: Jun 9, 2016
  18. Offline


    JBoss925 Ummm, why extend JavaPlugin?
  19. Offline


    In case people want to use it as a library so they can use it in more than 1 plugin. In order to do that they put it in their plugins folder and if I do not extend javaplugin it throws an error. If you use it as a Util then it's a matter of copy-pasting.:D
  20. https://gist.github.com/KingFaris10/37c2b099f14c6c9862dc

    That's just my example of a shortened Cuboid class to the max. You can also remove unnecessary constructors like the one taking in 6 integers, and I decided to keep the Map<String, Object> constructor in-case people wanted to make the class implement ConfigurationSerializable. In this way, I made my serialization serialize as a String.
    JBoss925 likes this.
  21. Offline


    JBoss925 Shouldn't really make it extend JavaPlugin, people can no longer make new instances of it without it throwing some kind of error or just having problems.
    That being said, I don't think you understand ConfigurationSerializable properly. You don't call the serialize/deserialize methods yourself, you simply directly set and get the object.
    getConfig().set("test", new Cubiod(...));
    Cubiod cubiod = (Cubiod) getConfig().get("test");
    That, and you never register the object as the Javadocs says (can be done in an initializer block if wanting to keep this independent of other classes)
    -Some other things:
    -Still comparing the world's names using ==, should be using String#equals() or checking world UIDs
    -You are putting an entire world into your serialize's Map, thus storing the world in your config when set, should be either the String or UID
    -iterator() should return your own iterator, an actual iterator, unlike what your CubiodIterator was.
    -Should really use Math.min/max, it looks better, and is probably a lot easier to read then the wall of text it currently is.
    Something not really important, but should be noted, instead of storing blocks as an ArrayList, could store it as a Collection, so that if you do ever change what type of collection (HashSet, LinkedList, etc), you wouldn't have to change it. Not really important, but if you are trying to maintain the "Lib" part, it may be of some importance.
  22. Offline


    As far as configurationserializable, it's an interface not a class so I must supply a Map<String, Object> for it to serialize.

    I'm currently removing JavaPlugin as I now realize that constructors will make it impossible to use practically.

    Sorry, I'll go ahead and switch to .equals().

    Yeah, serializing a world is a bit large I suppose, I'll change it to the world name.

    I'll go ahead and switch to Math.min and Math.max for readability.

    And as far as the storing blocks as an arraylist I have to define a type to add blocks. I've changed the return type to a Collection<Block> but I cannot directly instantiate Block with Collection<? extends Block>. If you know a fix please let me know.
  23. Offline


    JBoss925 You still instantiate the ArrayList, its just that it appears as a Collection to anyone using the Lib, so that if they do decide to use it, and you want to change the ArrayList to something else, it won't break them using it.
    As for the ConfigurationSerializable part, you've missed the point I made. You don't set/get it using the methods, you set/get the object directly. You don't set the Map<String, Object> to the config, you set the Cuboid. When getting, you directly get the Cuboid, not the Map<String, Object>. That, and you missed the part about registering it.
  24. Offline


    I'm assuming it's to be registered in the javaplugin class?

    EDIT: Also, I don't see how that's possible. ConfigurationSerializable is an interface and thus requires a serialize method in order for me to use it. Is there a way around this? Do I just put the cuboid object itself in the map along with a key like "cuboid"?

    By that I mean map.put("cuboid", <<Cuboid>>);
    <<Cuboid>> being the cuboid object.
  25. Offline


    JBoss925 No, I am not talking about the serialize method, I am talking about saving it to a config. In your section about serialization, you state that they should do something like this:
    Cuboid c = (...);
    getConfig().set("place", c.serialize());
    and for getting, they are calling the constructor.
    They shouldn't be doing this, which lead me to believe that you may not understand how it works.
    ConfigurationSerializable is made so that they can just directly call set/get on the object, rather then calling this serialize/deserialize method. This should be corrected, as the way you suggest defeats the whole purpose of implementing ConfigurationSerializable.
    As for registering it, you can register it any way you see fit, as long as it is registered once, whether that be in your onEnable(), an initializer block, a static initializer block, etc.
  26. Offline


    Ahhh I see. So you're saying the serialization method is supposed to be there but it will be called when serializing into the config automatically?

    EDIT: Also how am I supposed to registerClass()? Meaning what parameters do I put in? I tried Cuboid.class and other various methods but it returned an error.
  27. Offline


    JBoss925 You are supposed to put in Cuboid.class, what is the error?
    and yes, the methods are called by the get/set methods, so that all you have to do is put the Cuboid in/cast the returned object to Cuboid.
  28. Offline


    It's fine, I worked my way around it by assigning it via a method. And ok, I understand now.

    Added AxisAlignedBB methods but it's reliant upon blocks rather than double locations due to the pure nature of the cuboid. Should you want a playercuboid object, it's very feasible and I could pump it out in 5 minutes should you request it:D

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
    Last edited by a moderator: Jun 9, 2016
  29. Offline


    That's a really unnecessary dependency on NMS.

    I also need to question the way you've handled iterator creation; you're creating a collection of every single block in the cuboid just to iterate over them. If the cuboid contains millions of blocks, then you're pretty much guaranteeing some nasty server lag and memory wastage. There's no reason to cache every single block just to iterate; see how I do it here: https://github.com/desht/dhutils/bl...java/me/desht/dhutils/cuboid/Cuboid.java#L694

    I'd also recommend storing either a WeakReference<World> or the world's UUID rather than the World object directly - avoid the risk of memory leaks if a plugin is holding a reference to your cuboid when its world is unloaded.
  30. Offline


    Only thing is, I don't want more than 1 class.
Thread Status:
Not open for further replies.

Share This Page