[haiku-development] Re: My SetViewUI ... patch
- From: looncraz <looncraz@xxxxxxxxxxx>
- To: haiku-development@xxxxxxxxxxxxx
- Date: Tue, 6 Oct 2015 12:26:13 -0500
On 10/6/2015 10:11, Axel Dörfler wrote:
It's like a big wart when something sticks out from a coding style I'm
used to -- I don't even have to look close ;-)
I can understand that, my style is just quite drastically different,
favoring spacing, standard abbreviations, reduced line wrapping (no 80
char limit), and absolutely no need to name obvious parameters in
headers... for starters ;-)
I didn't mean that you should remove all comments. Just superfluous
ones, and those, that belong into the doxygen files. Documentation is
important.
I'll document the final version fully, I just removed the comments that
weren't really helping comprehension of the code. The rest of the file
is pretty barren, comment-wise, so I followed suit.
> rgb_color mix_color(rgb_color color1, rgb_color color2, uint8 amount)
(divide into two lines)
I really have no idea what you mean here.
C++ comments.
I'm bad at that...
Superfluous blank line (in a number of cases).
I'm wonderfully bad at that as well :-/
I also spotted the use of "new" without nothrow in the app_server --
you even checked against NULL afterwards, but that doesn't have any
effect at this point.
EEK! I *KNOW* better, LOL!
Also, you should really try to create cleaner patches: when you clean
up the coding style, you should *only* clean up the coding style.
Don't change code, don't insert a BAutolock somewhere when it wasn't
there before. When you can't behave while writing the code, "git add
-i" is your friend.
Thought I did, probably just forgot to commit some changes before doing
the style cleanup. My bad, will be more careful!
No idea of a better name for the scheduled message. I could hand over
ownership of a message and have it hold its own data, but that is more
prone to leaking memory and detracts from the ease of use.
I must admit that I don't understand the distinction between these
two, or rather, the reason for it. It just seems like extraneous code.
The DelayedMessage is a facility for building the data that will be sent
as a message. It is a throw-away object that doesn't own or copy any
data itself. It helps to ensure that the original attached data is
actually never copied if the message is merged, and new memory is only
allocated if merging fails (this could be easily done in other ways, of
course). It also helps to separate the responsibilities of the looper
from the messages (the looper being responsible for scheduling and,
originally, dispatching, the messages being responsible to ensure their
data is attached to a sender and sent to the correct place). But, above
all, it makes it much easier and cleaner to use.
DelayedMessage delayed(...);
delayed.Attach<>();
...
ScheduleMessage(delayed);
break;
vs
DelayedMessage* delayed = new(std::nothrow) DelayedMessage(...);
if (delayed == NULL)
break;
delayed->Attach<>();
...
if (ScheduleMessage(delayed) != B_OK)
delete delayed;
break;
When looking at the code it is helpful to keep in mind that I wrote this
with the idea that future fast-repeating messages could be merged easily
and that it would just be a little facility integrated with
MessageLooper. I'm still clinging to that idea :p
I haven't given up getting rid of the thread, if you don't want to
accept it with it still existing, I can totally accept that, I'll keep
digging to see if I found a bug with LinkReceiver's handling of the
timeout (first glance at the code didn't show anything immediately
obvious). One way or another, I will eventually get rid of that thread!
Another idea I had was to just find a way to reduce the number of
updates coming from BColorControl. But my mind might enjoy complexity a
bit too much, I admit. That, and I have no idea how to accomplish that
goal. I seem to remember a discussion on the list a few years ago about
that very topic and no solution ever being found.
- Space between function name and parameter parenthesis, for example:
"printf ()".
Where did you see this?
A number of times, actually.
> + bool operator < (const DMScheduledMessage&
other) const;
Would be one occasion, but there was more. You definitely fixed some
of those in your cleanup patches, though. I think I spotted one in
some header.
Ah, yes, not with the calls, though, like your original example, but
with the declarations - yeah, I'm REALLY good at doing that.
- Why prefix functions in the BExperimental namespace with exp_?
I have absolutely no idea!
Now that you remember: why not just remove them, and put their meat
into rgb_color directly?
They exist in ColorTools.cpp which has a nice OpenTracker license
attached. Wasn't sure if I should just remove that file. Actually
meant to ask, got distracted, and now we're here.
But, by "into rgb_color directly," do you mean something such as
rgb_color::MixWithColor(rgb_color other, uint8 amount)?
When you need more CPU then there is something wrong :-)
Exactly. I'm going to roll this out into userland again and see if I
can replicate the issue there, if not, it will really narrow down the
possible culprit of my issues... I've done far too much threading in my
life for something this simple to be so troublesome.
That's actually a good reason to have it in the client, too. Sending a
message to the app_server that will then remember to send itself
another message, in order to send a message back to the app seems like
quite more work and detours as needed.
True, on the client I'd simply do it as follows:
The first time a color is changed in Appearance the color_which value
would be set on an atomically test-and-set color_which member variable
only when it equals B_NO_COLOR, or is the same, and a thread would be
launched that would only allow setting the color every 8ms or so (120hz
rate). The thread would stay alive and keep polling the variable to see
if it was anything other than B_NO_COLOR.
If you'd prefer this way, then I'll jump right on it and remove all the
DelayedMessage code from the app_server entirely, though we will lose
DelayedInvalidate() at the same time... but there are ways around that,
naturally, but I think we'd lose a very valuable facility....
the app_server does that can be immensely useful to reduce the redraw
rate (I made extensive use of this in PhOS for animations). Useful to
reduce redraws, but not to control exactly when they happen.
Why not simply use a BMessageRunner for animations? Should work pretty
much in the same way.
DelayedInvalidate(8000); is a LOT easier than all the effort that goes
into using a BMessageRunner. In fact, I've made it a point in life to
never use it again if I can avoid it.
For example, you can use DelayedInvalidate() right in Draw() very safely
while still having some measure of redraw rate control.
Take this psuedo-code example for pulsing the navigation color or
something (I actually have a really nice idea with this, but I'm
focusing on this and font awareness first and foremost).
void
BTextControl::Draw(BRect upateRect)
{
... normal drawing code...
if (HasFocus()) {
... draw next color outline/effect
DelayedInvalidate(15000, effectRect);
}
}
I bet that's how Be did it and is why Dan0 had the method.
Be's implementation didn't merge repeats, though, so if you ran a tight
loop with DelayedInvalidate() calls, it you'd get each one of those
invalidations later.
My current implementation would mean that interim redraws won't result
in repeated firing of draw calls if they were identical, and the
existing code would possibly merge the rects as well, obviously.
The utility of this can't really be understated, once you use it a few
times, you really won't want to go back.
That said, this could also be accomplished client-side, but I really
don't have a good idea as to the best way of doing so.
ServerWindow and ServerApp implement their own loop code, so I have to
inject into that code. In addition, Desktop uses the default loop, so
I'd also have to override that.
For my tests, I only derive ServerWindow from DelayedMessageLooper, and
modify ServerWindow's _MessageLooper() to use
DelayedMessageLooper::GetNextMessage().
Not sure what you are getting at, since all subclass MessageLooper.
Apart from that, I think for a small limited feature like this the
code is quite invasive.
They subclass it, but then don't use its existing looper code at all,
they fully override it. Shouldn't really be a problem, though, so long
as DelayedMessageLooper gets first dibs at the message troph, which
requires only changing receiver.GetNextMessage(code) to
DelayedMessageLooper::GetNextMessage(code). If I can get rid of
DelayedMessageThread I'd be much happier.
The computational complexity of the DelayedMessage facilities, however,
is rather deceptive. In the end, a tiny throw-away object is created,
data is only copied once ONLY IF the data can't be merged (which it
usually can), and the amount of communications it saves can be drastic,
so it's a code-heavy, but deceptively lightweight, utility. Personally,
I'd leave it in for DelayedInvalidate alone. Being able to also crush
repeated set_ui_color calls and possibly other future heavy-hitting
calls just adds to the utility.
I'm not attached to the implementation, just what it accomplishes. Any
better ideas are very welcome.
The great thing is that it doesn't effect compatibility, so we can move
forward and replace it with whatever better idea comes along later.
I think I've hit the style cleanup pretty hard, examined everything in
git's diff output, and it seems like I have things covered. Obviously,
that's for you to de[r/c]ide ;-)
Looks like our checker tools need to become much better.
Would be helpful if they could go over a patch and recognize only the
lines which need to be examined. Running them on the patch itself
generated a list of faults four times larger than the patch file... I
didn't expect anything different, I was just being hopeful ;-)
Thank you for taking the time to look things over!
That's the spirit! Thanks for not letting this stop you :-)
Stop me? Ha!
I just have to make writing Haiku style-appropriate code second nature,
that takes practice :p
--The loon
Other related posts: