mIRC Home    About    Download    Register    News    Help

Print Thread
#228993 18/01/11 05:14 PM
Joined: Dec 2002
Posts: 254
T
Talon Offline OP
Fjord artisan
OP Offline
Fjord artisan
T
Joined: Dec 2002
Posts: 254
I've poked around and think i know how windows are handled in mIRC, so in theory this actually should be simple to add to mIRC and could result in some MAJOR benefits. A while back i was asking about how to handle knowing when new lines of text are appended to any given windows buffer because its extremely taxing or difficult to determine new lines accurately within a window when its buffer has reached maximum and starts trimming lines to append new ones.

If my guess is correct, mIRC has some sort of array of strings for lines, most likely a vector which is a class or typedef struct which contains information like stripped line, color coded line, line color, etc.. My reason for this guess is the actual buffer area for displayed text is really a static control which has no simple method of mutli-coloring text like that, so somewhere theres a buffer, a scrollheight is set on the scrollbar and a custom event given to the scrollbar/wm_paint/etc to update the window by some means of GDI drawing of text. This would explain why scrolling is also odd unlike most windows programs that use a built in control.

You know when a buffer is being appended to, trimmed, etc so by theory it should be an EXTREMELY simple implementation to fire off a "bufferchange/windowupdate/echo/whatever you wanna call it" event to signal that the last line in a window is new no matter what it is (script echo, join, part, quit, script error, disconnect, etc..)

I know it has been suggested in the past, and many people seem to reply it would be too difficult to implement but I really don't see how when somewhere that array of lines in a window is maintained.

Talon #229055 20/01/11 08:55 AM
Joined: Oct 2003
Posts: 3,641
A
Hoopy frood
Offline
Hoopy frood
A
Joined: Oct 2003
Posts: 3,641
I think the biggest problem is that you potentially end up with:

a) infinite loop scenarios,
b) duplicated event triggers, and
c) a possible performance issue

For (a), consider:

Code:
ON *:BUFFERCHANGE:*:#channel:echo -a # just got updated


Works fine if the active window is not #channel, but infinite loop if it is. This is why mIRC [generally] doesn't trigger events that can be initiated via /command.

As for (b), you would have many cases where something like an ON JOIN triggered, and then a BUFFERCHANGE event fired for what is effectively the same event. It makes sense, in theory, for a BUFFERCHANGE event to override a JOIN event, but consider what happens when BUFFERCHANGE scripts start popping up: your ON ^JOIN script becomes obsolete and likely overridden by a BUFFERCHANGE event-- so now everybody starts moving their JOIN event processing into the BUFFERCHANGE event to ensure their theme related stuff doesn't get changed by another script. This causes confusion in implementation, and a general mess. This is all hypothetical, of course-- but it's plausible IMO.

Finally, (c): There's probably some kind of performance hit here too, just for firing an event everytime something updates in a window. Given that Khaled has already been struggling to maintain performance in the window buffer, I don't think it would be wise to slow it down again.

I'm not specifically against this request, I'm just offering my opinion of why it was likely deemed "difficult" by others.

argv0 #229071 20/01/11 05:42 PM
Joined: Dec 2002
Posts: 254
T
Talon Offline OP
Fjord artisan
OP Offline
Fjord artisan
T
Joined: Dec 2002
Posts: 254
I see your point, i guess it would be more effective to give $line() a uniqueID which could be a double that increases for every line. a doubles range is +/–1.7E308 so mIRC would have to be running for a heck of a long time before it actually wraps around.

This way if you need to do something based on a buffer you could log the last uniqueID and next update find which ones are new, which would still effectively let you find lines which don't trigger an event, such as an echo or output from mIRC like retrieving channel modes when you pull up chan central.

There are countless ways to wind up in an infinite loop, so i don't see how this one would really be any different besides maybe having a problem with ctrl+break.

Also bufferchange is just supposed to let you know the last line is new, and not intended to be halted or even support the ^ like how on input doesn't allow ^, only messages you might want to format yourself so I don't see people using it to change how their themes work.

Either way, this is a much needed implementation as for now the only viable solution I can think of is to filter to an alias, the alias shove each line into a binvar, and md5 the binvar to see if it doesn't match from the last check, but even that has a potential fail if the buffers flooded with the same line over and over like a timer trying to use a /draw command and filling your buffer with insufficant parameters. Afterwards comes the problem of figuring exactly which ones are new using this filter method.

Outside filter, i've had suggestions for my situation for using $line. You can't rely on $line(window,0) because of the problem with the buffer being full, line 1 is erased and the new line appended so the total amount of lines doesn't change. You can't rely on the first line or the last line by logging because that introduces possible breakage due to repeated lines. $line(window,0) works fine up until the buffer has reached its limit.

If anybody can possibly think of a VIABLE mIRC-Only solution I'd love to hear it. It MUST be with the window buffer, following the log lines is NOT an option, not everybody logs.

Another thought, would be simmilar to bufferchange which would allow you to enable custom logging for a window to log to an alias. a log file keeps track of these things and keeps appending new lines to the log file, so rather than writing to a file, it'd be unique to log to an alias.

Or rather than logging to an alias you could have an event trigger like on LOG, because then your proposed infinite loop could be countered with "echo -g window blah has changed" because -g prevents the line from being logged to file. downfall would be even if loggings off, it'd still need to trigger which would still allow you to create your own custom logging method or use the data as needed.

Talon #229081 20/01/11 08:17 PM
Joined: Oct 2004
Posts: 8,061
R
Hoopy frood
Offline
Hoopy frood
R
Joined: Oct 2004
Posts: 8,061
Again, this still wouldn't be perfect, but just to add to your $line part that might at least give you something to work with for the time being...

Although $line(window,1) will be lost if your buffer is full and you add a new line and $line(window,0) won't change with a full buffer, this can actually work for you...

Step 1- Set a variable to the buffer size so you can use it later.

Step 2a- While $line(window,0) is less than the buffer variable, see if that total number of lines has changed. If so, you know a line was added.

Step 2b- If $line(window,0) equals or is greater than the buffer variable (greater than is just to catch any possibility of error), then check both $line(window,1) and $line(window,$line(window,0)) at whatever interval you want. If either one changes, then you have a new line.

Catch- Although this works in most cases (even if there are repeated lines at the bottom of the buffer as you mentioned), there is the possibility of having lines 1 and 2 be the same AND the new line matching the previous new line. That would mean that neither first nor last line changed even with an added line. However, this really should be rare unless your window buffer fills with the same error top to bottom as could happen with a bad loop. So I'd say this has somewhere around a 99% success rate, which isn't all that bad unless you absolutely need 100%. If nothing else, it gives you something decent to work with until something better can be set up.

How to increase accuracy further- Track more than just the first and last lines. Pick one or more other lines in the middle and track them as well. This still doesn't help in the case of a bad loop that fills the entire buffer with the same message, but does decrease the chance of randomly having the top lines be the same and have the new line match the previous new line.

Anyhow, just some thoughts that might be at least useful in the meantime.

Riamus2 #229090 20/01/11 10:39 PM
Joined: Dec 2002
Posts: 254
T
Talon Offline OP
Fjord artisan
OP Offline
Fjord artisan
T
Joined: Dec 2002
Posts: 254
yea thats a fairly good idea but still not 100% accurate.. I even thought about hooking the window procedure for each window and watching for WM_PAINT because theoretically that shows a new line, but also fails because changing focus on windows causes a re-paint of the given window thus triggering another WM_PAINT so even that won't work. I'm just totally at a loss of even a way to do it with a dll.


Link Copied to Clipboard