• 🏆 Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. 🔗Click here to enter!
  • It's time for the first HD Modeling Contest of 2024. Join the theme discussion for Hive's HD Modeling Contest #6! Click here to post your idea!

[Wurst] How can I accomplish "HashMap<item, function>"?

Status
Not open for further replies.
Level 4
Joined
Aug 14, 2005
Messages
49
Hi!

I'm currently in the process of rewriting my entire map in Wurst (yes, I think it's that awesome. My map is a GUI disaster, so this was urgently needed).

Now, I have a lot of situations where I need to do something whenever someone buys an item. In GUI, I did this with (a lot of) triggers that ran whenever someone bought an item and then simply using a condition to check for "the right item".

In Wurst, I had the idea of simply using a HashMap where I store all the items as keys and the function to be executed as corresponding values. Then, this would only need one trigger: If someone buys an item, look up in the hashmap which function to run for this item and execute it.

Obviously, writing this:

Code:
var item_functions = new HashMap<item, function>

Doesn't work. After some looking around, I tried:

Code:
var item_functions = new HashMap<item, code>

But here I get an error, saying: "Type parameters can only be bound to ints and class types, but not to code. You can provide functions codeToIndex and codeFromIndex to use this type with generics."

I tried looking this up, but I couldn't find information on these functions (codeToIndex and codeFromIndex) anywhere.

My current solution is to try and implement a kind of class wrapper

Code:
abstract class Function
    abstract function execute()

And simply write lots of (static?) classes that will wrap this with a corresponding function and then simply use this as my generic type for the HashMap. But before I do that, I was wondering if I am going at this all wrong and if there is either a smarter / already implemented way of achieving the same thing or how I can implement this codeToIndex and codeFromIndex

Thanks for reading and all the best
 

Jampion

Code Reviewer
Level 15
Joined
Mar 25, 2016
Messages
1,327
I think the reason why you cannot use code is, that you cannot have code arrays in jass.

The idea you have is close to what you are supposed to do in wurst (at least I think so).
You should use a closure.
Define an interface with only one function.
Then you can use this interface as parameter. The advantage of this approach is, that the function can have a parameter (for example the item).

Wurst:
public interface OnItemBuy
    function onItemBuy(item whichItem)

public class Test
    static constant itemToClosure = new HashMap<item,OnItemBuy>

    static function test()
        item someItem = null
        itemToClosure.put(someItem, (item itm) -> (print(itm.getDescription())))

You only need to define the interface once and then you can use the lambda expression, so you don't need to define a lot of static classes.


I gonna tag @Frotty to correct me in case I am saying something wrong.
 
Level 4
Joined
Aug 14, 2005
Messages
49
That looks really elegant and fantastic. Thank you very much!

I believe it would be fine to do the same for units and spells respectively as well, right? So, I can define interfaces "OnUnitBuy" and "OnAbilityCast", yes? Then I think this would make the whole code a lot cleaner, since all functions that then deal with abilities, items and units being created (bought or casted) are wrapped up in one place.
 

Jampion

Code Reviewer
Level 15
Joined
Mar 25, 2016
Messages
1,327
There are a lot of things possible with that.
You should check out the blog. It contains an elegant way to code spells using event listening and closures.
WurstScript • Best of the Wurst 5 - Late March Update

Usually you want to have a mapping from ability id (int) to effect (closure).
In the standard GUI way you have tons of triggers that run when an abiltiy cast and then you have a condition
ability id == ... for every trigger.
Here you have just one trigger and hastable lookup, so it should be a lot more efficient once you get more and more abilities.

Also you probably want item id and unit id instead of item/unit. Because when you buy those, you don't even have an object before that can be put into the hashmap.
 
Status
Not open for further replies.
Top