• 🏆 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!

Jasshelper 2011-12-19

Status
Not open for further replies.
Level 6
Joined
Jun 16, 2007
Messages
235
Jasshelper 2012-03-10

Latest version of jasshelper: 2012-03-10
Previous version was: 2012-02-10

JASS:
// while unit has some buff do some healing
while GetUnitAbilityLevel(whichUnit, 'Bhea') > 0
    call SetWidgetLife(whichUnit, GetWidgetLife(whichUnit) + 10.)
    call TriggerSleepAction(0.1)
endwhile

// print out numbers from 1 to 10 with for loop
for i = 1 to 10
    call BJDebugMsg(I2S(i))
endfor

// print only 1 2 3
for i = 1 to 10
    call BJDebugMsg(I2S(i))
    if i == 3 then
        break
    endif
endfor

// print out numbers from 10 downto 1
for i = 10 downto 1
    call BJDebugMsg(I2S(i))
endfor

// kill all units in a group
for enumUnit in someGroup
    call KillUnit(enumUnit)
endfor
// WARNING: groups are empty after for loop

Changelog:
//=====================================
// 2012-03-10
//=====================================
* Fixed a bug with //! external directive
* Fixed a bug with debug keyword

//=====================================
// 2012-02-10
//=====================================
* Fixed a small bug with //! import
* Changed program icon to make it clearly distinct from Vexorian's version

//=====================================
// 2012-02-09
//=====================================
* Fixed a problem with map not working when you have zero structs

//=====================================
// 2012-02-07
//=====================================
* Fixed library, scope, struct and module initialization orders.
* Fixed initialization order for structs not inside scope or library.
* InitTrig functions are no longer valid inside scopes and libraries.

//=====================================
// 2012-01-14
//=====================================
* fixed a bug that prevented new loops to be used with function interfaces

//=====================================
// 2012-01-07
//=====================================
* removed WEWarlock support (outdated)
* more speed improvements
* added full display of external tool calls (ObjectMerger)

//=====================================
// 2012-01-06
//=====================================
* removed FILEPP preprocessor (not enough public support for it)
* done some optimizations, jasshelper is now about 3x faster
* progress bar now shows global progres

//=====================================
// 2011-12-25
//=====================================
* included #bigdef and #foreach modules with FILEPP

//=====================================
// 2011-12-24
//=====================================
* added FILEPP preprocessor (executes before everything else in the map script)
* optimized for group loop as suggested by Troll-Brain.

//=====================================
// 2011-12-19
//=====================================
* added 3 for loops
* added while loop
* added break
Check out this section in jasshelpermanual:
Better looping: for, while, break

//=====================================
// 2011-12-17
//=====================================
* jasshelper now displays full textual progress when used from WE.
* jasshelper will now warn you to reopen your map if you used //! external command
 

Attachments

  • JHProgress.png
    JHProgress.png
    40.6 KB · Views: 468
  • jasshelper 2012-03-10.7z
    1.3 MB · Views: 972
Last edited:

Bribe

Code Moderator
Level 50
Joined
Sep 26, 2009
Messages
9,456
I agree with all above changes. One of the biggest improvements which can be made to the parser is to avoid annoying module-initializer blocks, basically something like this:

JASS:
initblock
    //Do stuff
endinitblock

//which compiles to:

private module initblockmod<random number>
    private static method onInit takes nothing returns nothing
        //Do stuff
    endmethod
endmodule
private struct initblock<random number> extends array
    implement initblockmod<random number>
endstruct
 
@mckill:It is because they are not native to the normal jasshelper. Those are features that cohadar added so ofc they won't be bolded yet neither by the jass tags nor by the editor. ;)

Also, as far as I know, cohadar isn't working on optimization (yet) so the parser will probably be about the same speed.

@Mag: If someone repackages jass newgen as a new version, then everyone will update. (the new update would have the rtc bug removed, the updated jass helper, and it would have the latest grimext hotfix)
 
Last edited:
Level 17
Joined
Apr 27, 2008
Messages
2,455
I'm not even sure that 'UnitEvent___n!!!' is a valid integer.
Last time i check it has to be one or 4 characters.
And special characters counts to one, such as the line break :'/n'

Anyway it's a pjass bug, in the token.l file :

UNITTYPEINT (['][\x01-\x26\x29-\x5B\x5D-\x7F]([\x01-\x26\x29-\x5B\x5D-\x7F][\x01-\x26\x29-\x5B\x5D-\x7F][\x01-\x26\x29-\x5B\x5D-\x7F])?['])

It's not a jasshelper one.

No to mention that it won't be the same expected value and probably would overflow even if it's a valid syntax.
Now a valid fix would be to convert such integers in decimal value, but really pJass should be fixed, not add some new stuff for jasshelper preprocessor.

EDIT : Oh wait, i got it, meh i won't delete my post, if there is someone which is willing to update pJass, because this is allowed in jass, but not for pJass :

local integer i = '/n'
 
Level 6
Joined
Jun 16, 2007
Messages
235
Can we also get a fix on that parsing bug that changes this:

private constant integer UNITS_UNIT_EVENT = 'n!!!'
to this:

constant integer UnitEvent___UNITS_UNIT_EVENT = 'UnitEvent___n!!!'

>_>
That is already fixed.

@Bribe
break is simply better than exitwhen true.
Besides I added it to be consistent,
every programming language that has for and while loops also has a break.

When I get someone to update TESH so new keywords are bolded properly there will be a new JNGP release, until than please download and test this.
 

Dr Super Good

Spell Reviewer
Level 63
Joined
Jan 18, 2005
Messages
27,180
// kill all units in a group
for enumUnit in someGroup
call KillUnit(enumUnit)
endfor
// WARNING: groups are empty after for loop
This is incorrect behaviour of how an iterator should work. The contense of the group should remain unchanged after the loop completes unless code within the loop performs changes.

The way you are currently treating it is more like a buffer. Where you pop each element out of it until all elements are processed and the container is empty. As far as I know people never use a for loop with a buffer in a way that would be fesible to compile to efficient JASS.

You would better off making a special keyword for this behaviour such as..

JASS:
// kill all units in a group
destructive for enumUnit in someGroup
    call KillUnit(enumUnit)
endfor
// WARNING: groups are empty after destructive for loop

// kill all units in a group
for enumUnit in someGroup
    call KillUnit(enumUnit)
endfor
// group contense untouched after for structure.
 
Level 6
Joined
Jun 16, 2007
Messages
235
This is incorrect behaviour of how an iterator should work.
I agree, but it is also the most optimized way to implement a group loop.
(FirstOfGroup + GroupRemoveUnit)

In almost all cases in mapmaking you don't need a group after the loop.
(groups are usually destroyed after the loop anyways)

When you do need a group to stay intact you will just need to use ForLoop native and enum function.

EDIT:
of course if someone finds a way to implement for loop that does not remove units from group I will just recode implementation and everyone will be happy. (it has to be fast, so no dumb solutions with copying the whole group and similar are acceptable)
 
Last edited:

Dr Super Good

Spell Reviewer
Level 63
Joined
Jan 18, 2005
Messages
27,180
The problem is you are violating standard programming logic with that instruction which could potentially confuse people about its behaviour. It is implicit that a for loop will not change the contense of the structure it is itterating through for anyone who has used a language like python or java. Yours however does not do so.

Instead of fighting programming conventions, just change the syntax of the structure to something like "destructive for" and then throw a syntax error with a normal "for" used in that situation stating it is unsupported due to inefficient implementation and that the scripter should use the inbuilt enum in that situation.

(groups are usually destroyed after the loop anyways)
Groups are usually never destroyed for efficiency reasons. A lot of common uses can share the same global constant group for the reasons you stated (as they always end up emptry after the function finishes execution). The only time groups are dynamicly allocated and destroyed is when their content needs to persist or more than 1 is required at the same time.
 
Level 6
Joined
Jun 16, 2007
Messages
235
Instead of fighting programming conventions...
jass is neither java nor C, it has its own programming conventions and a lot of them are a lot more weird than a for that clears the group.

In fact this type of loop that clears the group is already used by and known by everybody in the community so I don't really see a problem here.

The syntax stays the way it is.
 
Level 6
Joined
Jun 16, 2007
Messages
235
Well basically Vex not being around any more, and me being the only one with enough programming education to handle the code.
(others have tried and failed before)

My reputation in wc3c community does not hurt either.
 
Level 31
Joined
Jul 10, 2007
Messages
6,306
and me being the only one with enough programming education to handle the code

Ahem, I know that super good and I can also handle the code, it's just a bloody programming nightmare >.>. It breaks like every convention possible to just butcher the readability >.<. If you managed to sift through the like 60,000 line files of code and figure out where everything was, good for you ; ).
 

Dr Super Good

Spell Reviewer
Level 63
Joined
Jan 18, 2005
Messages
27,180
and me being the only one with enough programming education to handle the code.
So you went to highschool? Wow I used to think WC3C people were smart post graduates until now. I also was not aware that everyone on this site was stuck in primary school. Hmm using your logic I must be unable to use computers in any way shape or form let alone type messages. Oh wait...

Next to the code being a mess and having no documentation, you hardly need vast programming experience to understand it. You do however need vast quantities of time to find out where and how to insert new structures into the system due to its bad design and documentation.
 
Level 6
Joined
Jun 16, 2007
Messages
235
Ahem, I know that super good and I can also handle the code, it's just a bloody programming nightmare
See the conditional you used there? So my answer is, no you can't.

So you went to highschool?
I am a computer engineer (28 years old).

Next to the code being a mess and having no documentation, you hardly need vast programming experience to understand it. You do however need vast quantities of time to find out where and how to insert new structures into the system due to its bad design and documentation.
See the conditional you used there?
Only if it was easy we could do it too. :goblin_cry:

Besides if any of you actually bothered to look at the new source you would have noticed that it is not a total nightmare any more because I broke it down in pieces and I actually wrote some comments in important areas.

Number of .pas files in 0.A.2.B.jasshelper = 35
Number of .pas files in new jasshelper = 58

Well hurray, jasshelper is not so hard any more, maybe now you can do it too.
For starters you can do things you were complaining about.
Nestharus can update modules to take arguments like macros.
Dr Super Good can implement for-group loop so it does not destroy the group.
 
Level 31
Joined
Jul 10, 2007
Messages
6,306
See the conditional you used there? So my answer is, no you can't.

Actually, it meant that we didn't want to do it, not that we couldn't do it ; P.

I am a computer engineer

So is Super Good, and so am I >.<, lol.

Number of .pas files in 0.A.2.B.jasshelper = 35
Number of .pas files in new jasshelper = 58

That is good to hear =o, lol. Only thing it needs to go on to now is like google code or an svn repo because multiple people can't be updating it like this. Actually, an svn repo would be best methinks ; ).
 
Level 6
Joined
Jun 16, 2007
Messages
235
Some philosophies of thought claim than not having the will to do something is the same as not being able to do something.

I prefer Mercurial for version control.

If you are serious about helping I can always create one more sourceforge project.
 

Dr Super Good

Spell Reviewer
Level 63
Joined
Jan 18, 2005
Messages
27,180
Dr Super Good certainly isn't.
For 1 and a half more years. Of which 1 year is spent on specalist subjects which are largly unrelated to general software engineering so I am prety much a software engineer. Yes he should have more practile experience seeing how he should have 7 years of work experience or a docterate and 4 years of work experience but that purly influence how confident he is at making changes and how efficiently they can be made and not that people like me without all that can not make them.

The fact is that if he makes changes like this the standard version of JASShelper then THW has to adopt it for its spell resources and scripting help. I do not think adding illogical structures is a way to improve JASShelper constructivly. We have enough nonsense to deal with already using normal JASS (such as no code arrays) and do not need more like for loops which empty the contense of a group. I do not mind the concept but to avoid implicit confusion it should be given a different syntax.
 
Level 31
Joined
Jul 10, 2007
Messages
6,306
For 1 and a half more years. Of which 1 year is spent on specalist subjects which are largly unrelated to general software engineering so I am prety much a software engineer. Yes he should have more practile experience seeing how he should have 7 years of work experience or a docterate and 4 years of work experience but that purly influence how confident he is at making changes and how efficiently they can be made and not that people like me without all that can not make them.

The fact is that if he makes changes like this the standard version of JASShelper then THW has to adopt it for its spell resources and scripting help. I do not think adding illogical structures is a way to improve JASShelper constructivly. We have enough nonsense to deal with already using normal JASS (such as no code arrays) and do not need more like for loops which empty the contense of a group. I do not mind the concept but to avoid implicit confusion it should be given a different syntax.

/agree



Updating the standards requires adherence to what people expect or vast improvement that proves that the old methodology was wrong. The group enum for loop accomplishes neither of these.


/thinks he sounded cool just now
 
Level 6
Joined
Jun 16, 2007
Messages
235
Updating the standards requires adherence to what people expect or vast improvement that proves that the old methodology was wrong. The group enum for loop accomplishes neither of these.
Anyone who has ever done a single group loop with FirstOfGroup expects the group to be empty after it, like I said jass is not a general purpose language, and jassers are not software students.

The group enum accomplishes exactly what it was designed to accomplish,
making group spells easy to write and easy to read.
I am not going to add an ugly keyword in front of it just to satisfy someones ideas of "logical"
If you want to complain to someone complain to blizzard for not adding proper group iterators.

In the mean time we will do it my way because I am the one doing all the work. Which in any way does not suggest that I don't know what I am doing or that I will add crazy shit into jasshelper.
 
Level 31
Joined
Jul 10, 2007
Messages
6,306
Anyone who has ever done a single group loop with FirstOfGroup expects the group to be empty after it, like I said jass is not a general purpose language, and jassers are not software students.

The group enum accomplishes exactly what it was designed to accomplish,
making group spells easy to write and easy to read.
I am not going to add an ugly keyword in front of it just to satisfy someones ideas of "logical"
If you want to complain to someone complain to blizzard for not adding proper group iterators.

In the mean time we will do it my way because I am the one doing all the work. Which in any way does not suggest that I don't know what I am doing or that I will add crazy shit into jasshelper.


Yea, but then that means that the community likely won't use what you're making. If you don't make what the community wants, then the community doesn't accept it ; \.


Unless you're doing this for fun, it'd be pretty pointless to update jasshelper then wouldn't it? : P
 
Last edited:
Level 29
Joined
Mar 10, 2009
Messages
5,016
wow you guys are computer engineers and/or 'will be', me not engineer nor
programmer nor will be(maybe), my english is not even as good as you guys
yet I know these things in less than 6 months, but anyway who gives a
s***, coz Im just a plain man who likes to mod WC3 and I bet you
like it also...so cut the crap & update Jasshelper as efficient as possible...

I think you should put an option if a user wants the unit to be removed from
the group loop just like bj_wantDestroyGroup coz seriously, not all people
want it that way...who needs the ForGroup native anyway if this can be
done correctly?...
 
cohadar said:
and jassers are not software students.
Right!!!

anyways this looks cool, gotta subscribe... ^_^

always loved that "for" and "while" loops...

and yeah, I think its better if you don't remove the units inside the group and just let people add a groupclear command after the loop if they want it, or better yet add 2 versions, one which clears the group and one that doesn't...
 
Level 6
Joined
Jun 16, 2007
Messages
235
This looks interesting. I'm going to wait before I actually update to this though because it does make my compile time longer than the older one.

It's just a psychological effect because now you can also see progress text, not just flashing progress bar.

Anyways I am currently adding C proprocessor to jass,
so I was wondering does anyone actually need that.
 
Level 17
Joined
Apr 27, 2008
Messages
2,455
Anyways I am currently adding C proprocessor to jass, so I was wondering does anyone actually need that.

You mean that we can have defines ?

Also for the First Of Group Loop, maybe you could use the accronym fog, instead of for.
This way, the user always keeps in mind that is not an usual for.
It could be a terrible idea, but i had to say it.

Also i'm quite sure that using a fog loop and a dummy group would still be more efficient that using a ForGroup call, just because each ForGroup call opens a new thread.
Well, i'm curious enough to test it right now.

EDIT : Hmm, no you can't use a fog loop on a group which is kept during time, because a ghost unit (unit removed of the game) will return null when FirstOfGroup will be called.
 
Level 6
Joined
Jun 16, 2007
Messages
235
Exactly, so there is no point in keeping group alive after a loop.

C proprocessor would basically be a standard replacement for all half-assed preprocessing features in jass.
Textmacros, modules, optional, static ifs.
 
Level 14
Joined
Nov 18, 2007
Messages
1,084
It's just a psychological effect because now you can also see progress text, not just flashing progress bar.
Being as obsessive as I am, I already timed how long this JassHelper took in compiling a script and compiling a map and compared it to the old one. In both cases, the older one was faster for my computer.

But if you add something amazing to JassHelper, I won't hesitate in switching over. :p
 
Level 6
Joined
Jun 16, 2007
Messages
235
Ok C preprocessor feature is experimental (using filepp atm) and I am open to other suggestions.

I did not know that LUA could be used as a preprocessor.
Even so any preprocessor in jass needs to satisfy these constraints:

It has to understand and preserve both single line and multiline comments
// /**/

It must parse all characters (for example some preprocessors don't allow $ because they reserve it for macros)

It must be easy to use. This is the most important part.

If LUA satisfies all those criteria please write some macro definitions in LUA so I can see how it works.

Small note:
Borland C preprocessor was not used because it reserves $ (this conflicts with //! textmacros)
Gnu C preprocessor was not used because it has too many library dependencies.
MCPP preprocessor was not used because it did not preserve // comments
M4 was not used because it proved too hard to use. (cryptic syntax)

In the end FILEPP was selected as the only viable alternative.
(unless someone comes with a better one)
 
Level 31
Joined
Jul 10, 2007
Messages
6,306
Well, Lua actually works a bit differently. What I'm saying is that you could make people use Lua like a preprocessor and include easy write to JASS script, for example like this

Code:
#i = 0
#while i < 10 do
    #print("local integer i" .. i .. "=" .. i .. "\n")
#end


Essentially, the JASS code would be treated as constant print commands and everything else would be Lua. So print each line or w/e and then when encountering Lua, execute that code and make it open the current JASS file being written to for writing using append mode =). It'd essentially allow you to code whatever you wanted to code with Lua without the need for modules or anything. Then Lua can be used directly to use those modules or w/e ;p. Some preprocessor features just aren't powerful enough to do what some systems need be done. The reason I wrote the Lua Framework was to allow for this dynanism: writing dynamic JASS code on the fly ; ).
 
Level 6
Joined
Jun 16, 2007
Messages
235
That LUA thing sounds terribly complicated.

New Version: 2011-12-25

Table using #bigdef #endbigdef (example of new macro usage)
JASS:
library Table
//***************************************************************
//* Table object 3.0
//* ------------
//*
//*   set t=Table.create() - instanceates a new table object
//*   call t.destroy()     - destroys it
//*   t[1234567]           - Get value for key 1234567
//*                          (zero if not assigned previously)
//*   set t[12341]=32      - Assigning it.
//*   call t.flush(12341)  - Flushes the stored value, so it
//*                          doesn't use any more memory
//*   t.exists(32)         - Was key 32 assigned? Notice
//*                          that flush() unassigns values.
//*   call t.reset()       - Flushes the whole contents of the
//*                          Table.
//*
//*   call t.destroy()     - Does reset() and also recycles the id.
//*
//*   If you use HandleTable instead of Table, it is the same
//* but it uses handles as keys, the same with StringTable.
//*
//*  You can use Table on structs' onInit  if the struct is
//* placed in a library that requires Table or outside a library.
//*
//*  You can also do 2D array syntax if you want to touch
//* mission keys directly, however, since this is shared space
//* you may want to prefix your mission keys accordingly:
//*
//*  set Table["thisstring"][ 7 ] = 2
//*  set Table["thisstring"][ 5 ] = Table["thisstring"][7]
//*
//***************************************************************

//=============================================================
    globals
        private constant integer MAX_INSTANCES=8100 //400000
        //Feel free to change max instances if necessary, it will only affect allocation
        //speed which shouldn't matter that much.

    //=========================================================
        private hashtable ht
    endglobals

    private struct GTable[MAX_INSTANCES]

        method reset takes nothing returns nothing
            call FlushChildHashtable(ht, integer(this) )
        endmethod

        private method onDestroy takes nothing returns nothing
            call this.reset()
        endmethod

        //=============================================================
        // initialize it all.
        //
        private static method onInit takes nothing returns nothing
            set ht = InitHashtable()
        endmethod

    endstruct

    //Hey: Don't instanciate other people's textmacros that you are not supposed to, thanks.
#bigdef TABLE_MACRO(NAME, TYPE, KEY)
    struct NAME extends GTable

        method operator [] takes TYPE key returns integer
            return LoadInteger(ht, integer(this), KEY)
        endmethod

        method operator []= takes TYPE key, integer value returns nothing
            call SaveInteger(ht,  integer(this)  ,KEY, value)
        endmethod

        method flush takes TYPE key returns nothing
            call RemoveSavedInteger(ht, integer(this), KEY)
        endmethod

        method exists takes TYPE key returns boolean
            return HaveSavedInteger( ht,  integer(this)  ,KEY)
        endmethod

        static method flush2D takes string firstkey returns nothing
            call NAME(- StringHash(firstkey)).reset()
        endmethod

        static method operator [] takes string firstkey returns NAME
            return NAME(- StringHash(firstkey) )
        endmethod

    endstruct
#endbigdef

TABLE_MACRO(Table, integer, key)
TABLE_MACRO(StringTable, string, StringHash(key))
TABLE_MACRO(HandleTable, handle, GetHandleId(key))

endlibrary
 
Level 31
Joined
Jul 10, 2007
Messages
6,306
Actually, it's pretty easy to code if you know how to design it :\.


Whenever running into Lua, close the JASS file, pass the Lua block to the grimoire object merger (seems to be a good bet), open the Lua file for writing using append and override print to write or w/e, then boom =). Ofc, this would mean that the c preprocessor stuff wouldn't be so hot then, but you'd have all of Lua at your disposal, which is quite a lot better. Quite easy to code (given that jasshelper is designed correctly).


Unless ofc this is too much for you? : P
 
Level 6
Joined
Jun 16, 2007
Messages
235
I was not talking about how complicated it would be for me to make it,
but how complicated it would be for people to actually use it.

First people would have to learn LUA.
Learning another full language just to do a little preprocessing is expecting too much from mappers.
And doing it with print statements is just zomg.

Classical macro preprocessing (no matter what preprocessor you use) is like ten times more simpler.

Yeah LUA is very powerful, but using it for preprocessing is like learning to fly a space shuttle so you can go shopping for cabbage.
 
Level 31
Joined
Jul 10, 2007
Messages
6,306
Stuff I do requires that power for preprocessing, hence why I wrote the Lua Framework >.>.


I have one lib that is actually 100% dynamic JASS code, purely generated from Lua. Why? It needs looped over dynamic var names and looped over indexes and a million other things as well as dynamically generated constants. 99% of the code depends on dynamism. The only things that don't depend on it are the function names and the locals ;p.
 
Status
Not open for further replies.
Top