Thread: [KT] Safe and Easy Container

Results 1 to 6 of 6
  1. #1 [KT] Safe and Easy Container 
    nbness2#5894

    nbness2's Avatar
    Join Date
    Aug 2011
    Posts
    599
    Thanks given
    224
    Thanks received
    96
    Rep Power
    254
    Feedback is appreciated

    Over the years I have witnessed multiple shoddy implementations of item containers.
    One that returned a Boolean on success or fail (this was on the right track in this way, but it was not specific enough. why did it fail?)
    One wouldn't check max amounts and overflow.
    One WOULD check max amounts and not overflow, but the remaining item disappeared.
    One wouldn't check if given ind(ex/ices) were valid.
    One wouldn't check if an item was in the slot the client said it was in.
    One wouldn't properly handle errors.
    One would keep an array of Short for item ids, an array of Int for an item amount and an array of Int for item charges (even if the item actually had no charges). This... system. It was present in ALL item containers. Equipment, Inventory, Bank, Store, etc. THAT was a real pain in the ass to read and make big changes to.

    Welcome to Container.
    I got the idea of creating Container after years of witnessing the atrocities listed above.
    Container is an interesting different way to go about handling Container operations. Well, compared to what I have seen out in the wild. So, I figured I would rewrite some common code in to something a bit different and... Modern? Isn't functional programming all the rage these days?
    Container tries to solve a lot of the logistical problems that people have when working with Containers, while also promoting a safer more direct way of handling possible errors.

    Here's some features that give credit to the Safety and Clarity of Container:
    • With Container, the safety and clarity of your code go hand in hand. There is a plethora of return types, as well as a neat Option-like functional functions that allow you to handle each scenario individually without having to use a when statement every time.
    • There is an Option inspired return type ContainerResult with functional methods that allow you to handle the results how you like.
    • You can handle them on an individual basis.
    • You can handle them on a more generic basis (Handle either Success or Failure).
    • Only handle what you want! The rest will disappear in to the void.
    • There are functions that handle the basics (Shifting, adding and removing items, etc) for you.
    • There are a few basic verification functions (verify that 1 item X is in slot Y, verify that X items Y are in slot Z), as well as one you can use for yourself.
    • You have to completely change the calling code to handle it in the "unsafe" way (container.unsafe), as the equivalents between the two dont return the same things in nearly all cases.
    • The source code is self documenting. The code you write is very likely to be self documenting too.


    Here's some cons of using Container:
    • No way to force you to handle all the different ContainerResults
    • It's less performant (not noticeable in realistic scenarios) than the more "traditional" ways of handling this kind of stuff, but safety always comes at the cost of performance when talking about code.


    Container is an interesting and very different way to go about handling Containers and what they can return, at least compared to what I have seen out in the wild. I figured this might bring them a bit more in to the modern world.

    Spoiler for links:

    Note: As of v1.13, this code also includes a BaseItem class (and the corresponding ItemDefinitions class) that Container is compatible with. This will likely be extended to a more generic Container in the future as I want to achieve better compatiblity with other peoples' already existing code!
    This also includes my ItemDefinitions.idf file that was created in End-ish 2018.
    There ARE tests, they are just a bit meh because this doesn't have very extensive functionality (and im pretty new to writing tests)

    Get the code: [Only registered and activated users can see links. ].
    Recently learned how to use gradle and also make the library in to a jar so thats: [Only registered and activated users can see links. ]


    Due to the nature of being developed in Kotlin, Container is meant to be written in Kotlin. This is mainly thanks to Extension functions and lambda functions. I don't guarantee anything feels good to write in Java!

    Spoiler for examples:

    In both of these examples, ContainerResult.Success.* and ContainerResult.Failure.* were imported, hence why theres no "Success.PartialAddItem" or whatever (thats how sealed classes work)

    Here's a hypothetical example. You can put in item X, and if there isn't enough room for all of item X, it will still add as much as it can and give you back what it couldn't put in.


    And here's my real life code example for how I handle dropping an Item.

    Discord: nbness2#5894
    Python Framework (???): [Only registered and activated users can see links. ]!
    NBX: [Only registered and activated users can see links. ]!
    DropTable DSL: [Only registered and activated users can see links. ]!
    Make your Inventory easier and safer to work with. Introducing Container: [Only registered and activated users can see links. ]
    Reply With Quote  
     

  2. #2  
    nbness2#5894

    nbness2's Avatar
    Join Date
    Aug 2011
    Posts
    599
    Thanks given
    224
    Thanks received
    96
    Rep Power
    254
    Update: 2019/03/14 - v1.14-1
    • Added a lot of documentation to the source code
    • Fixed a few logical bugs leading to Exceptions (missed testing a very specific scenario, added a test for that scenario)
    • Stripped BaseItem and ItemDefinition to prepare for genericizing


    Link to release: [Only registered and activated users can see links. ]

    My next step is to make this as generic as I can. Of course I can't make it COMPLETELY generic, as I have to know what properties to access when adding an item, removing an item, anything having to do with accessing properties. Or maybe I can...
    Discord: nbness2#5894
    Python Framework (???): [Only registered and activated users can see links. ]!
    NBX: [Only registered and activated users can see links. ]!
    DropTable DSL: [Only registered and activated users can see links. ]!
    Make your Inventory easier and safer to work with. Introducing Container: [Only registered and activated users can see links. ]
    Reply With Quote  
     

  3. #3  
    Wut can u tell when theres nothin to say

    Tyrant's Avatar
    Join Date
    Jul 2013
    Age
    19
    Posts
    1,478
    Thanks given
    617
    Thanks received
    361
    Rep Power
    785
    I don't quite get it by the example... why does somebody who want to add a simple function have to do all of these things? Should be done automatically





    [Only registered and activated users can see links. ]
    Reply With Quote  
     

  4. Thankful user:


  5. #4  
    nbness2#5894

    nbness2's Avatar
    Join Date
    Aug 2011
    Posts
    599
    Thanks given
    224
    Thanks received
    96
    Rep Power
    254
    Quote Originally Posted by Tyrant View Post
    I don't quite get it by the example... why does somebody who want to add a simple function have to do all of these things? Should be done automatically

    I'm not sure I fully understand the question, but here's my attempt to answer.

    First off, that example was from my own project NBX, so it will of course not look like a dropItem function you or someone else might write.
    That's an example of how I use it, as I use every result to either log information perform an action or both.
    You also don't HAVE to use named parameters, I mostly use them for clarity when multiple consecutive parameters are the same type and it may be confusing to the reader.

    What Container doesn't do is automatically do anything for you outside of the container itself.
    What Container does do is provide you the means to operate on the results of more specific scenarios with data relevant to that scenario (if any) while also not throwing any exceptions for say a NullPointerException or IndexOutOfBoundsException.
    This avoids ambiguous returns (like a container returning false on any error that might happen rather than throw an exception) and gives you a more obvious way to handle the relevant data.
    If you want to, you can also use the more generic onSuccess or onFailure though there won't be any relevant data returned with it (though I am thinking of changing that, having all possibly relevant data rather than no relevant data)

    Here's the minimum code for dropping an item.
    This is assuming you don't want to handle any bad results like a bad index result or an item id mismatch result, both of which are most likely player forged packets if you are handling this in a packet handler. Personally, I'd want to know if people were trying to cheat by dropping an item that wasn't actually there or crash the server with a pesky unhandled exception.
    This is an attempt to only handle what result you want from this, making the developer "not have to do all those things" to write a simple function.
    Code:
    fun droptemPacket(player: Player, slotIndex: Int, itemId: Int) {
        player.inventory.takeFrom(slotIndex)
            .onSuccessType<FullTakeItem> { World.dropItem(containedItem) }
    }
    This player.inventory.takeFrom call will still return bad results, but you don't HAVE TO handle them.
    The relevant data is the taken item in the form of containedItem (a property of ContainsItem which FullTakeItem extends).
    When handling FullTakeItem, you can use it inside of that scope.
    Discord: nbness2#5894
    Python Framework (???): [Only registered and activated users can see links. ]!
    NBX: [Only registered and activated users can see links. ]!
    DropTable DSL: [Only registered and activated users can see links. ]!
    Make your Inventory easier and safer to work with. Introducing Container: [Only registered and activated users can see links. ]
    Reply With Quote  
     

  6. #5  
    Imagine-PS
    FiveRiverFlo's Avatar
    Join Date
    Jun 2013
    Age
    38
    Posts
    523
    Thanks given
    16
    Thanks received
    67
    Rep Power
    37
    Quote Originally Posted by Tyrant View Post
    I don't quite get it by the example... why does somebody who want to add a simple function have to do all of these things? Should be done automatically

    His code makes it so any situational result can have an action associated with it. Instead of checking manually each time if item can successfully be put in inventory, just tell his container system what you want it to do when it is a success or a fail or other situations and it'll handle it for you. And it looks neater and is easier to understand.
    Spoiler for Vouch:
    Quote Originally Posted by Cobalt. View Post
    Vouch for him. He did some php work for me and I had no problems with him.
    Quote Originally Posted by cool pker View Post
    I vouch for this nigga! quality work mate.
    Quote Originally Posted by Elixium View Post
    Vouch, Does AMAZING work! Also is very quick/friendly!
    Quote Originally Posted by Hank View Post
    Vouch for my bb.
    Quote Originally Posted by Mithallas View Post
    vouch for cache work
    Quote Originally Posted by Inyx View Post
    Vouch for this nub Done Auto Cache Downloader for me
    Quote Originally Posted by satucre View Post
    Vouched, really good guy, he is fast and he do really good work ! He is really friendly and we always want to buy more stuff ! Thanks you ! Keep it up
    Quote Originally Posted by Mr Lonely View Post
    Big vouch!
    Reply With Quote  
     

  7. Thankful user:


  8. #6  
    nbness2#5894

    nbness2's Avatar
    Join Date
    Aug 2011
    Posts
    599
    Thanks given
    224
    Thanks received
    96
    Rep Power
    254
    Quote Originally Posted by FiveRiverFlo View Post
    His code makes it so any situational result can have an action associated with it. Instead of checking manually each time if item can successfully be put in inventory, just tell his container system what you want it to do when it is a success or a fail or other situations and it'll handle it for you. And it looks neater and is easier to understand.
    This is exactly correct, you get to pick what you handle.
    Don't want to do anything when the addItem returns a ContainerFull? Don't write the onSuccessType that handles ContainerFull!
    Discord: nbness2#5894
    Python Framework (???): [Only registered and activated users can see links. ]!
    NBX: [Only registered and activated users can see links. ]!
    DropTable DSL: [Only registered and activated users can see links. ]!
    Make your Inventory easier and safer to work with. Introducing Container: [Only registered and activated users can see links. ]
    Reply With Quote  
     


Thread Information
Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

Similar Threads

  1. [KT] Safe and Easy Container
    By nbness2 in forum Snippets
    Replies: 3
    Last Post: 03-15-2019, 05:35 AM
  2. Replies: 34
    Last Post: 09-22-2010, 11:23 PM
  3. Replies: 2
    Last Post: 12-02-2008, 09:50 PM
  4. Replies: 57
    Last Post: 02-19-2008, 10:42 PM
  5. [Req]Danger, safe and server title on screen![Req]
    By Grim Line in forum Tutorials
    Replies: 2
    Last Post: 09-27-2007, 06:04 PM
Tags for this Thread

View Tag Cloud

Posting Permissions
  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •