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

[Snippet] Thread

Level 31
Joined
Jul 10, 2007
Messages
6,306
Troll-Brain, ur idea was a bit different. Actually, it was a lot different. I was struggling to find a way to sync the threads up and the sync selections thing was perfect for that (first got idea from azlier, already well aware of it when u were discussing). As I said myself, the strength of sync selections is that it operates as soon as it is sync'd =).
 
Level 17
Joined
Apr 27, 2008
Messages
2,455
Random suggestion, i've not really thought about it, but instead of a boolean you could use a static real and then use the real variable event.
This way you will know exactly when it will be synced, on event, but maybe it will kill all the purpose of it.

Oh and i would still love a test of my solution, it could be the best option if you only need to sync one or few small integers within a short delay (let's say real case), because the sync time could be the least, it could also be the worst but a test is needed.
 
Level 17
Joined
Apr 27, 2008
Messages
2,455
I know, but i believe your way is bit more delayed because you're likely to use one more TriggerSyncReady as needed, i mean the loop will be ended a few time after the sync was done.

Now if the delays of unit selections are added rather than be done "at the same time", then it's obvious that my way sucks hard.
But you just can't guess, a test is needed for that.
 
Level 31
Joined
Jul 10, 2007
Messages
6,306
Troll-Brain, yours has mass syncs for each integer. It may be viable for syncing booleans, but I think that a near instant sync of 2500 32 bit integers trumps 32*2500 syncs of the same amount of data using unit selections (each sync also having an associated firing trigger). And yes, I am talking about syncing -(2^31) 2500 times >;o, all 32 bits filled rawr.
 
Level 17
Joined
Apr 27, 2008
Messages
2,455
Troll-Brain, yours has mass syncs for each integer. It may be viable for syncing booleans, but I think that a near instant sync of 2500 32 bit integers trumps 32*2500 syncs of the same amount of data using unit selections (each sync also having an associated firing trigger). And yes, I am talking about syncing -(2^31) 2500 times >;o, all 32 bits filled rawr.

Theroritic cases are so fun, give me a map where you need an "instant" which is not instant at all btw, sync of 2500 integers, and more 32 bits one.

You're not going to convince me until a test is done.
For now i still think that my solution could be the fastest in term of sync time, but yes it should be the least efficient one and it could also be the slowest in term of sync time.

The funny part is that actually i hate my way and love your's, but that doesn't change the fact that a test is needed.
 
Level 31
Joined
Jul 10, 2007
Messages
6,306
Just do 80000 unit selections on a unit with a registered trigger and see how long it takes. If it beats 16 seconds (which is what 2500 took), then it wins. If 40000 beats 1.5 seconds (which is what 1250 took, 2500 is slower due to wc3 cap limit on data), then 40000 wins.

And yes, those are recorded numbers. In my tests, I watch the download rate and have a timer running in the background to see how long the complete download takes =). The cap is 60 syncs/second after you do your initial burst (yes, that is recorded as well).
 
Level 17
Joined
Apr 27, 2008
Messages
2,455
You keep to ignore what i'm saying.

I'm talking about syncing one or only few integers within a short delay (let's call it real case), and check in how much time the sync occurs.
80 000 trigger evaluation is obviously going to lose, it will lag as hell ...
 

Bribe

Code Moderator
Level 50
Joined
Sep 26, 2009
Messages
9,464
This is how I see your library, without the "Nestharus nonsense" ;)

JASS:
library Thread /* v1.0.0.0
*************************************************************************************
*
*   This script allows one to sync up threads between players. It is most useful for
*   preventing players from desyncing due to heavy local code blocks as well as syncing
*   up large streams of data.
*
************************************************************************************
*
*   SETTINGS
*/
globals
    /*
    *   This unit can be retrieved from the map attached to this thread. Copy and paste
    *   the unit in the map into target map and then put the unit type id of that unit here.
    */
    private constant integer UNIT_SYNC_ID = 'h001'
endglobals
/*
************************************************************************************
*
*   struct Thread
*
*       readonly boolean synced
*           -   Loop until this is true
*
*       static method create takes nothing returns Thread
*       method destroy takes nothing returns nothing
*
*       method sync takes nothing returns nothing
*           -   Call from local player when that local player's operation is complete
*
*   Examples
*
*       local Thread thread = Thread.create()
* 
*       loop
*           if (GetLocalPlayer() == targetPlayer) then
*               //the hefty operation here should segment how much it does per iteration
*               //too much per iteration and slower computers will desync from the sheer magnitude
*               //of the operation
*               //this will have to be fine tuned based on the size of the operation
*               if (doHeftyOperation()) then
*                   call thread.sync()
*               endif
*           endif
*
*           call TriggerSyncReady()
*           exitwhen thread.synced
*       endloop
*
*       call thread.destroy()
*
*************************************************************************************/
    struct Thread
        private unit threadSyncer
        
        private static trigger syncThreadTrigger
        readonly boolean synced
        
        static method create takes nothing returns thistype
            local thistype this = allocate()
            
            if threadSyncer == null then
                static if LIBRARY_UnitIndexer then
                    set UnitIndexer.enabled = false
                endif
                
                set threadSyncer = CreateUnit(Player(0), UNIT_SYNC_ID, WorldBounds.maxX, WorldBounds.maxY, 0)
                call SetUnitUserData(threadSyncer, this)
                call PauseUnit(threadSyncer, true)
                call SetUnitPosition(threadSyncer, 99999, 99999)
                
                call TriggerRegisterUnitEvent(syncThreadTrigger, threadSyncer, EVENT_UNIT_SELECTED)
                
                static if LIBRARY_UnitIndexer then
                    set UnitIndexer.enabled = true
                endif
            endif
            
            return this
        endmethod
        
        method destroy takes nothing returns nothing
            set synced = false
        
            call deallocate()
        endmethod
        
        /*
        *   Call within a local block
        */
        method sync takes nothing returns nothing
            call SelectUnit(threadSyncer, true)
            call SelectUnit(threadSyncer, false)
        endmethod
        
        private static method syncThread takes nothing returns boolean
            local thistype this = GetUnitUserData(GetTriggerUnit())
            
            set synced = true
            
            return false
        endmethod
        
        /*
        *   Struct Initialization
        */
        private static method onInit takes nothing returns nothing
            set syncThreadTrigger = CreateTrigger()
            call TriggerAddCondition(syncThreadTrigger, Filter(function thistype.syncThread))
        endmethod
    endstruct
endlibrary
 
Level 31
Joined
Jul 10, 2007
Messages
6,306
Hmm, I'm very confused about this resource. I don't quite get why you would need that or even what it exactly does?

Can you give an example situation where this might be useful?

if you don't know where it would be useful, then you personally have no use for it =)

I already explained where it would be useful in the docs. If you don't understand, go study more JASS =).
 

Zwiebelchen

Hosted Project GR
Level 35
Joined
Sep 17, 2009
Messages
7,236
if you don't know where it would be useful, then you personally have no use for it =)

I already explained where it would be useful in the docs. If you don't understand, go study more JASS =).
Wasn't meant as an offense ... I just don't know when you would have "heavy local blocks" that desync... usually all stuff you do locally is fast as hell anyway. Don't know. Maybe its interesting for your external data read stuff. Can't really think of a situation.
 
Level 31
Joined
Jul 10, 2007
Messages
6,306
Consider reading 1000 files from a player's hard drive. That player is the only one with those files obviously, so it's a local operation. You also have to process all of that data (120*12 chars per file) and transmit it all. It's an operation large enough to cause op limit if you don't do it properly. It would obviously also cause a desync.
 
Level 31
Joined
Jul 10, 2007
Messages
6,306
It's funny how you keep to avoid the question.
Basically we are asking for a concrete example of usage.

Already answered. Question wasn't avoided.

Not going to waste my time on this any further. I've learned in the past that this all leads to absolutely nothing but hours and hours of pointless debate.

If you don't know what to use it for, don't use it, that's my advice. If you don't like that answer, live with it, cuz that's the only answer you're getting =).
 
Give a map where you would need to sync hundred of integers.

Any ORPG map.
SotP has some hundreds and hundreds of integers that get saved for the user,
so a multiplayer ORPG map with things like Talent tree systems, custom inventories,
custom stats, custom player xp, custom player level, player statistics (like wins,
loses, total playtime), etc... would need hundreds of integers too. Maybe close to
a thousand.

I was working on a map that needed to store all of the above and MUCH more (like
items, abilities, quests complete, quests pending, quests undiscovered, etc...)
 
Level 31
Joined
Jul 10, 2007
Messages
6,306

???

I used two machines across Garena + got other people to help test. I spent probably 40 hours testing this code and other related code (4 days, all day each day). I tested many, many different scenarios and used users that had both low pings and high pings. We also did things like pausing the game. Furthermore, I also tested this with tons and tons and tons of other synchronizations (100,000+).


The only thing I haven't tested is when a player has 12 units selected. If Mag was going to test something, it'd be that ; ).
 
Top