- Joined
- Nov 4, 2007
- Messages
- 337
Well, the name 'Optibug' is quite strange. But I couldn't think of a better one.
I made this to make debugging more clear.
I like automatic-working-systems, so you don't need extra functions.
You just have to use BJDebugMsg.
What does this exactly do?
It prevents that systems spam the same error message like
100 times per second. Messages that are similar are only displayed
once in X (20) seconds when you use BJDebugMsg and this system.
But it has got mechanisms to prevent big performance losses, too.
Read the systems code for further information.
Feel free to post constructive feedback.
I made this to make debugging more clear.
I like automatic-working-systems, so you don't need extra functions.
You just have to use BJDebugMsg.
What does this exactly do?
It prevents that systems spam the same error message like
100 times per second. Messages that are similar are only displayed
once in X (20) seconds when you use BJDebugMsg and this system.
But it has got mechanisms to prevent big performance losses, too.
Read the systems code for further information.
JASS:
library Optibug requires Table
//===========================================================================
// Information:
//==============
// Do you know the stupid fact that you want to debug your systems, and they spam exactly the same
// message like 100 times per second? Well, this solves that problem.
// But I have to warn you: This will hook BJDebugMsg.
// So it wouldn't be such useful if you used BJDebugMsg for displaying messages to all players.
//
// What does this exactly do?
// It registers the usages of the BJDebugMsg function and ensures that messages that are 'similar'
// are only displayed one time in X seconds. If the displayed strings are just are bit different, like
// if they contain different integers, the system updates them and marks them as 'similar'.
//
// Bad about this is, that it uses really a lot of your CPU. You can prevent causing too much
// lag, by modifying the constants.
//
//===========================================================================
// Implementation:
//===============
//
// 1. Download a tool called 'JassNewGen', and unpack it somewhere. You need that
// edit to use this tool. The 'JassNewGen' is used very commonly and offers other
// nice features. You can find it at:
// [url]http://www.wc3c.net/showthread.php?t=90999[/url]
// 2. Make a new trigger, and convert it to custom text. Insert everything
// the library contains into that trigger.
//
// 3. Download a system called 'Table' from this link:
// [url]http://www.wc3c.net/showthread.php?t=101246[/url]
// Do the same installation stuff for 'Table' as for this system.
//
// 4. Save your map and enjoy :-)
//
//===========================================================================
// The constants:
// ==============
//
// RECYCLE_INTERVAL : How often are errors displayed? When do their values get recycled?
// MIN_STRING_MATCH : This system checks if strings from the data storage match with new strings.
// How similar must two strings be to be 'similar'?
// PASS_INTERVAL : How often are data passed to the recycler? Unimportant!
// MAX_INSTANCES : How many instances of different debug messages shall this handle maximally (right adverb?)?
// PERFORMANCE_VALUE : If the Optibug func is used for more than PERFORMANCE_VALUE times in RECYCLE_INTERVAL seconds,
// the system stops doing it's job: Because it would screw up ypur computers otherwise.
//
// =================================================================================================================
globals
private constant real RECYCLE_INTERVAL = 20.
private constant real MIN_STRING_MATCH = 70.
private constant real PASS_INTERVAL = 1.5
private constant integer MAX_INSTANCES = 15
private constant integer PERFORMANCE_VALUE = 250
endglobals
globals
private integer passCount = 0
private string array passData
private integer recycleCount = 0
private string array recycleData
private timer Recycler = CreateTimer()
private timer PassTimer = CreateTimer()
private StringTable RegisterTable
private boolean RecycleThreadRunning = false
private integer PF_counter = 0
endglobals
private function RecycleData takes nothing returns nothing
loop
exitwhen recycleCount == 0
set recycleData[recycleCount] = ""
set recycleCount = recycleCount - 1
endloop
set RecycleThreadRunning = false
call StartPassTimer.execute()
set PF_counter = 0
endfunction
private function PassData takes nothing returns nothing
if RecycleThreadRunning == false then
loop
exitwhen passCount == 0
set recycleCount = recycleCount + 1
set recycleData[recycleCount] = passData[passCount]
set passCount = passCount - 1
endloop
set RecycleThreadRunning = true
call PauseTimer(PassTimer)
call TimerStart(Recycler,RECYCLE_INTERVAL,false,function RecycleData)
endif
endfunction
function StartPassTimer takes nothing returns nothing
call TimerStart(PassTimer,PASS_INTERVAL,true,function PassData)
endfunction
private function IsStringSimilarTo takes string a, string b, real percentage returns boolean
local string tempa
local string tempb
local integer max = StringLength(a)+StringLength(b)
local integer similar = 0
loop
exitwhen a == "" or b == ""
set tempa = SubString(a,StringLength(a)-1,StringLength(a))
set a = SubString(a,0,StringLength(a)-1)
set tempb = SubString(b,StringLength(b)-1,StringLength(b))
set b = SubString(b,0,StringLength(b)-1)
if tempa == tempb then
set similar = similar + 2
else
if StringLength(a) > StringLength(b) then
set b = b+tempa
elseif StringLength(b) > StringLength(a) then
set a = a+tempb
endif
endif
endloop
if I2R(similar)/I2R(max) >= percentage*0.01 then
return true
endif
return false
endfunction
// Check if the new string is similar to any registered string.
// At the same time this refreshes the errors.
private function MatchesSomeData takes string whichOne returns boolean
local integer i = 0
local boolean bool = false
// We kill two birds with one stone here:
// We check, wether the string is similar to one from the data storage
// And we 'redisplay' everything.
loop
set i = i + 1
exitwhen i > passCount
if bool == false then
if IsStringSimilarTo(whichOne,passData[i],MIN_STRING_MATCH) then
set passData[i] = whichOne
set bool = true
else
call DisplayTextToPlayer(GetLocalPlayer(),0,0,passData[i])
endif
else
call DisplayTextToPlayer(GetLocalPlayer(),0,0,passData[i])
endif
endloop
set i = 0
loop
set i = i + 1
exitwhen i > recycleCount
if bool == false then
if IsStringSimilarTo(whichOne,recycleData[i],MIN_STRING_MATCH) then
set recycleData[i] = whichOne
set bool = true
else
call DisplayTextToPlayer(GetLocalPlayer(),0,0,recycleData[i])
endif
else
call DisplayTextToPlayer(GetLocalPlayer(),0,0,recycleData[i])
endif
endloop
return bool
endfunction
private function Optibug takes string s returns nothing
if passCount + recycleCount < MAX_INSTANCES then
set PF_counter = PF_counter + 1
if PF_counter < PERFORMANCE_VALUE then
call ClearTextMessages()
// Displaying the messages is included in 'MatchedSomeData'
if MatchesSomeData(s) == false then
set passCount = passCount + 1
set passData[passCount] = s
endif
endif
else
if passCount + recycleCount == MAX_INSTANCES + 1 then
call DisplayTextToPlayer(GetLocalPlayer(),0,0,"Disabled 'Optibug' due to heavy performance flaws.")
endif
endif
endfunction
hook BJDebugMsg Optibug
private function Init takes nothing returns nothing
call StartPassTimer()
endfunction
endlibrary
Feel free to post constructive feedback.