- Joined
- Jul 10, 2007
- Messages
- 6,306
vJASS Standard 4
_______________________________________________________________________________________________________________________________________________________________________ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Last edited:
vJASS Standard 4
_______________________________________________________________________________________________________________________________________________________________________ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
globals
//anything in here is a global
endglobals
struct omg extends array
//any variables in here that aren't inside of a method are fields
endstruct
_myField does not compile last time I checked.
_myField compiles within structs, but not as a global.
When you use _myField, it will also compile.
Why are you limiting it in the Jass's section only?, this should be implemented in the Spell's section as well or as a rule...
mckill said:Why are you limiting it in the Jass's section only?, this should be implemented in the Spell's section as well or as a rule...
I spam the Jass Resource Section with useless scripts that no one uses, and because I haven't used them yet, they end up being buggy while getting approved.
Sorry for not answering (RL is evil), but with this intentions and your interest in not to form a closed circle of coders, that's pretty good. Jut keep with open mind and enjoy the game.moyackx, we have current standards, they just aren't really documented anywhere
The current standard is vJASS Standard 3. Standard 1 was defined on wc3c, standard 2 on TH, and standard 3 on THW. Why do you think some stuff that works perfectly gets rejected? Because they don't follow Standard 3.
We're now moving on to Standard 4, which is a much stricter version of Standard 3 ;o. Standard 4 is there to ensure that all resources have 0 bugs when being approved with proof that they were tested for 0 bugs. It's also there to ensure that all resources have proper error checking (I know that I personally get really lazy on checking for errors a lot of the time cuz error checking is annoying). It's about raising the quality of resources .
vJASS Standard 4, like Standard 3, will only apply to the JASS Section. Spells section will continue to follow a very relaxed Standard 3.
The reason wc3c died was because they did not allow for new innovations. Once they approved one resource of a type, then they would never ever approve a new resource of the same type regardless of any innovation in it or dif pros/cons. THW follows a very different philosophy, which allows people to continue to innovate.
What we can and probably should do is create a new forum called JASS Lab, where people can put up experimental code that may not have lots of error checking and stuff ;o.
edit
And also, believe me, with Standard 4, I am hurting myself more than anyone else. I'd have to redo the majority of my resources + create toolchains to make some of them possible under standard 4 >.<. Not much can even be written under Standard 4 until a good jasshelper thing is created because some of the requirements will raise syntax errors under the current jasshelper.
if we dont enforce things, people will not learn...if there is no law to jail people who shoplift, then what would the world be?...
But... convention ;________;
if the_map_maker has ALWAYS_THE_SAME_CONVENTION then
call BJDebugMsg("that doesn't matter that much")
else
call BJDebugMsg("ok that's bad, time to read this one or an other")
endif
Standards != rules
In general, it is not possible to catch all user errors or it would be too much work to do it. Maybe relax this condition a bit.A resource must catch all possible user errors with the use of ErrorMessage.
In general, it is not possible to test all possible cases. Maybe relax this and just say all nontrivial functions in the API should be tested.A resource must be tested, checking for all possible cases.
In general this is not possible with tests.… to prove that the resource is free of bugs
Silently ignoring errors is not a good idea in my opinion. It can lead to very strange and hard to find bugs. Removing error messages should only happen in performance critical code (e.g. fast periodic code, inner loops, etc.)Error checking is debug only
I think this should only apply for performance critical code. Or it there an other reason which speaks against using them?Interfaces/Function Interfaces Aren't Allowed
This one was really "wtf?" for me. Could you explain why extending structs is a problem? I think it is more important that the library i readable, because that makes it easier to check it.Extending Structs (Due To OnDestroy) Is Not Allowed, As Such All Structs Must Extend Array To Prevent Struct Extension
- Textmacros must be used only internally (Maybe there are a few exceptions where it makes sense to have a textmacro in the API but this should be very rare)
- Modules must be syntactically complete (for example if a module includes the beginning of a function it must also include 'endfunction').
Yes, I agree that textmacros are sometimes the best way to do something. But I would say that if you have the choice between using plain functions/structs/modules and using textmacros you should not use textmacros.Textmacros and modules are totally useful by breaking these rules. Granted, the learning curve is intense at time to import such a script, but it provides functionality/safety/abstraction that's not possible doing it any other way.
I don't understand your third suggestion. Do you have an example?
method startMissile(real x, real y, real directionRadians, real distance, real speed)
Same applies for interfaces and function interfaces. If I want to pass a function to another function it is absolutly neccessary to use a function interface. At the moment I'm working on a library for nonlinear optimization and without a function interface its not possible to pass a user defined cost function to the optimization algorithm. The user would have to modify the system code to pass his functions which is not acceptable.
Error checking and relying on ErrorMessage is ok, but forcing people to upload testcases which cover all possible errors is completly impossible and impractical. But as Systems like Trigger got approved without providing any of those testcases, I guess this isn't required anyway.
A function interface is a trigger. You can do the same thing with modules and triggers. I show how in a tutorial. It's also much faster >.<.
you can create arrays in struct extends array just fine >.>, you just need to do the math yourself instead of letting jasshelper do it for you
Well, with Trigger, I did in fact test everything, I just didn't upload the test code >.<.
call Optimization.minimize(costfunction, parameter)
. With this approach all the optimization algorithms would have to be copied to every struct that uses the minimization. That breaks encapsulation. I want to collect all optimization methods in one struct and not copy them around into every struct that needs them.Multiple arrays too?
A function interface is a trigger. You can do the same thing with modules and triggers. I show how in a tutorial. It's also much faster >.<.
function interface CostFunction takes real r returns real
function MyCostFunction takes real r returns real
return I2R(2*2*2*2*2*2*2*2*2*2*2)
endfunction
struct InterfaceTest extends array
private static method minimize takes CostFunction tfun, real para returns real
return tfun.evaluate(para)
endmethod
private static method callback takes nothing returns nothing
local integer i = 0
local CostFunction costFun = CostFunction.MyCostFunction
loop
exitwhen i > 150
call minimize(costFun, 1.0)
set i = i + 1
endloop
endmethod
private static method onInit takes nothing returns nothing
call TimerStart(CreateTimer(), 0.001, true, function thistype.callback)
endmethod
endstruct
struct InterfaceStruct extends array
private static trigger eventTrig = CreateTrigger()
private static trigger fireTrig = CreateTrigger()
static thistype data = 0
private static method onEvent takes nothing returns boolean
local integer prevData = data
set data = 5 //event data
call TriggerEvaluate(fireTrig)
set data = prevData
return false
endmethod
private static method onInit takes nothing returns nothing
call TriggerAddCondition(eventTrig, Condition(function thistype.onEvent))
endmethod
static method register takes boolexpr bc returns nothing
call TriggerAddCondition(fireTrig, bc)
endmethod
endstruct
module INTERFACE_MODULE
static if thistype.MyCostFunction.exists then
static method minimize takes nothing returns boolean
call thistype(InterfaceStruct.data).MyCostFunction(1.0)
return false
endmethod
private static method onInit takes nothing returns nothing
call InterfaceStruct.register(Condition(function thistype.minimize))
endmethod
endif
endmodule
struct InterfaceTest extends array
private static method MyCostFunction takes real r returns real
return I2R(2*2*2*2*2*2*2*2*2*2*2)
endmethod
private static method callback takes nothing returns nothing
local integer i = 0
loop
exitwhen i > 150
call minimize()
set i = i + 1
endloop
endmethod
private static method onInit takes nothing returns nothing
call TimerStart(CreateTimer(), 0.001, true, function thistype.callback)
endmethod
implement INTERFACE_MODULE
endstruct
code
.module INTERFACE_MODULE
static if thistype.MyCostFunction.exists then
static method minimize takes nothing returns boolean
call thistype(InterfaceStruct.data).MyCostFunction(1.0)
return false
endmethod
private static method onInit takes nothing returns nothing
call InterfaceStruct.register(Condition(function thistype.minimize))
endmethod
endif
endmodule
minimize
is used as a trigger condition it can't take any parameters. The 1.0 in MyCostFunction should be passed as a parameter, not as a hardcoded value, otherwise this doesn't make sense.static if thistype.index.exists then
static if thistype.deindex.exists then
private static method onInit takes nothing returns nothing
call RegisterUnitIndexEvent(Condition(function thistype.onIndexEvent),UnitIndexer.INDEX)
call RegisterUnitIndexEvent(Condition(function thistype.onDeindexEvent),UnitIndexer.DEINDEX)
endmethod
else
private static method onInit takes nothing returns nothing
call RegisterUnitIndexEvent(Condition(function thistype.onIndexEvent),UnitIndexer.INDEX)
endmethod
endif
elseif thistype.deindex.exists then
private static method onInit takes nothing returns nothing
call RegisterUnitIndexEvent(Condition(function thistype.onDeindexEvent),UnitIndexer.DEINDEX)
endmethod
endif
struct InterfaceStruct extends array
private static trigger eventTrig = CreateTrigger()
private static trigger fireTrig = CreateTrigger()
static thistype data = 0
private static method onEvent takes nothing returns boolean
local integer prevData = data
set data = 5
call TriggerEvaluate(fireTrig)
set data = prevData
return false
endmethod
private static method onInit takes nothing returns nothing
call TriggerAddCondition(eventTrig, Condition(function thistype.onEvent))
endmethod
static method register takes boolexpr bc returns nothing
call TriggerAddCondition(fireTrig, bc)
endmethod
endstruct
module INTERFACE_MODULE
static if thistype.MyCostFunction.exists then
static method minimize takes nothing returns boolean
call BJDebugMsg("minimize!")
call thistype(InterfaceStruct.data).MyCostFunction(1.0)
return false
endmethod
private static method onInit takes nothing returns nothing
call InterfaceStruct.register(Condition(function thistype.minimize))
endmethod
endif
endmodule
struct InterfaceTest extends array
private static method MyCostFunction takes real r returns real
call BJDebugMsg("costfunction!")
return I2R(2*2*2*2*2*2*2*2*2*2*2)
endmethod
implement INTERFACE_MODULE
private static method onInit takes nothing returns nothing
// Parameters?
call minimize()
endmethod
endstruct