• Listen to a special audio message from Bill Roper to the Hive Workshop community (Bill is a former Vice President of Blizzard Entertainment, Producer, Designer, Musician, Voice Actor) 🔗Click here to hear his message!
  • Read Evilhog's interview with Gregory Alper, the original composer of the music for WarCraft: Orcs & Humans 🔗Click here to read the full interview.

[Discussion] vJASS Standard 4

Level 14
Joined
Dec 12, 2012
Messages
1,007
Ok,

lets take DDS as an example. Lets say you have this code:

JASS:
struct Test extends array

    private static method onDamage takes nothing returns nothing
    endmethod        

    implement DDS
endstruct

In this example, onDamage would be my cost function, which gets called by the module interface implemented by DDS.

The method onDamage can use various "parameters" like damage, damageModifiedAmount, damageOriginal and so on. But thats strictly spoken different to a function interface, because those parameters come from the system code. What I want and need is to pass parameters from the user scope.

So lets consider this example:

JASS:
struct Test extends array

    private static method costfun takes nothing returns real
        return 0.0
    endmethod        

    implement Optimization

    private static method onInit takes nothing returns nothing
        // Lets imagine minimize is a static method of the struct Optimization
        // This method then calls costfun several times. How should I access
        // now to the parameters 1.0 and 5.2 from costfun without loosing
        // abstraction by storing them in some placeholder fields of Optimization?
        call Optimization.minimize(1.0, 5.2)
    endmethod        
endstruct

With a function interface thats very easy, it would just be:

JASS:
struct Test extends array

    private static method costfun takes CostFunction costfun, real para1, real para2 returns real
        return 0.0
    endmethod        

    private static method onInit takes nothing returns nothing
        local CostFunction costfun = CostFunction.costfun

        call Optimization.minimize(costfun, 1.0, 5.2)
    endmethod        
endstruct

Short, easy to read and I can pass the parameters directly from the user scope, as the system Optimization itself doesn't have anything to do with them. costfun is just a BlackBox for the system, in contrary to DDS where the system decides which values are passed to the user function.

I don't say that this is a bad thing, actually for a system like DDS (and most of all other systems) that approach is perfect and exactly how I would do it too.

But for a very little amount of systems, I think function interfaces make more sense and therefore should be allowed in such exceptions.
 
You have access to the two parameters, it's magic.

The system has 2 global variables, it sets them to the two parameters, then it calls all functions registered to the system.


Done.

Any other examples? Clearly the first thing with the module is simpler than the second thing (in real scenarios). The second thing you gave is a very unrealistic scenario, it would normally have much more code associated with it. The first thing however is a realistic scenario.


If you are just talking about wanting to use your function directly, then use it directly, don't even bother with a function interface ;).
 
Level 14
Joined
Dec 12, 2012
Messages
1,007
I already posted a valid example: a generic optimization library.

Basically every optimization library works like this:
Matlab
C++
Java
and so on

The system has 2 global variables, it sets them to the two parameters, then it calls all functions registered to the system.

Yes, but then I have to rely on those placeholder variables and can't just use the ones from my functions parameter list. That means I have to know and remember those names. Also this won't work when calling another cost function from the running cost function.

If you are just talking about wanting to use your function directly, then use it directly, don't even bother with a function interface ;).

No, because I might have multiple costfunctions with the same signature. Thats why function interfaces are so practical here.

Any other examples? Clearly the first thing with the module is simpler than the second thing (in real scenarios). The second thing you gave is a very unrealistic scenario, it would normally have much more code associated with it. The first thing however is a realistic scenario.

It is a realistic szenario in the case of a nonlinear optimization library. Of course in 99,9% of the cases it wont and function interfaces should not be used.

But I still have the opinion that here they make sense.
 
Yes, but then I have to rely on those placeholder variables and can't just use the ones from my functions parameter list. That means I have to know and remember those names. Also this won't work when calling another cost function from the running cost function

You can pass them in too, and wtf, it will work when calling a cost function from a running cost function, it'll work perfectly, lol.

Does not UnitIndexer work with nested events? What about DDS? There's no reason why this wouldn't work as well. You simply need to know how to make it work ;), and doing that is easy.

No, because I might have multiple costfunctions with the same signature. Thats why function interfaces are so practical here.

Multiple structs ;)

Also, passing in options/filters like that is unreasonable to do in JASS. That'd be a major performance hit. When you'd want to use function interfaces for things like filters/options, you shouldn't even do that thing in the first place, do it in another language ;P.
 
Level 14
Joined
Dec 12, 2012
Messages
1,007
You can pass them in too, and wtf, it will work when calling a cost function from a running cost function, it'll work perfectly, lol.

Does not UnitIndexer work with nested events? What about DDS? There's no reason why this wouldn't work as well. You simply need to know how to make it work ;), and doing that is easy.

Well thats true, but its not nice to code. You have to used predefined names for your cost function and use the predefined parameter names from the Optimization struct.

And adding a new costfunction with a new signature will cause a lot of work because you have to index all parameters to allow those nested calls. When you now add a signature with four parameters instead of three you will have to adapt the indexing too.

With a function interface you just modify the interface signature on the top of the library and the function call in the optimization algorithm, nothing more.

Multiple structs ;)

Well, thats quite lame :D

And to be honest, I don't see the big performance hit when using function interfaces. I had to call the costfunction 150 times every 0.001 seconds to see a small difference.
 
Modules are easier on the user for events. For things other than events, like filters and options, it's best not to do them in the first place.

edit
And adding a new costfunction with a new signature will cause a lot of work because you have to index all parameters to allow those nested calls. When you now add a signature with four parameters instead of three you will have to adapt the indexing too.

Indexing? huh?

JASS:
local integer prev = var
set var = new
call event.fire()
set var = prev


Look up my tutorial on custom events
 
Level 14
Joined
Dec 12, 2012
Messages
1,007
Modules are easier on the user for events. For things other than events, like filters and options, it's best not to do them in the first place.

Lol, so the "solution" is "not do it"? Because of a performance drop that is hardly measurable? You can't be serious :D


Indexing? huh?

Look up my tutorial on custom events

Well, that uses indexing, either with a stack or a list, but still you index the event data, so what?
 
Lol, so the "solution" is "not do it"? Because of a performance drop that is hardly measurable? You can't be serious :D

Ahem, for filters/options, there is no solution. You wouldn't be using modules, triggers, or anything, heh. There is no performance to compare it against ;p. Filters/options just aren't recommended under any circumstances ;). You can do those in SC2 just fine though.

Well, that uses indexing, either with a stack or a list, but still you index the event data, so what?

What?

JASS:
globals
    private trigger myEvent = CreateTrigger()
    private integer data = 0
endglobals

function OnMyEvent takes boolexpr c returns nothing
    call TriggerAddCondition(myEvent, c)
endfunction
function FireMyEvent takes integer d returns nothing
    local integer prev = data //store the previous data in a local
    set data = d
    call TriggerEvaluate(myEvent)
    set data = prev //set the data back to the previous value
endfunction
function GetEventData takes nothing returns nothing
    return data
endfunction


The only stack being used here is the JASS scratch stack
 
Level 14
Joined
Dec 12, 2012
Messages
1,007
Ahem, for filters/options, there is no solution. You wouldn't be using modules, triggers, or anything, heh. There is no performance to compare it against ;p. Filters/options just aren't recommended under any circumstances ;). You can do those in SC2 just fine though.

But why?

I nearly finished the library and it works completly fine, so I don't get what should be the problem.
 
Level 23
Joined
Apr 16, 2012
Messages
4,041
I will summarize it: People shouldnt give a fuck about performance until their resource laggs at reasonable levels and rather write readable code

Filters/options just aren't recommended under any circumstances ;).

yea, arent recommanded by who?

I dont want to be dick but arent you getting a little bit egoistic(What I say everyone say, when I say its slow, its slow no matter what etc)?
 
Why is this still being discussed anyway?
This should have come like 9 years ago.
Now you have 95% of the resources that don't follow any real convention.

I personally like the different styles of coding in (v)JASS (well, some of them). It's just a scripting language, and one that's pretty easy to follow so regardless of the style it should look relatively similar. Although shitty variable names and bad indentation is no excuse lol. And yeah, it's a little late for this standard but I understand it's just a reference for those who care.
 
Top