That's a really interesting observation, as far as the string printing/tooltip conventions work, as far as there not actually being conversion. I've had a tendency to assume that the tooltip printing indicated that conversion was happening, but it really just prints according to the port type... wild! Fascinating info. I totally understand what the problem is with the splitter... I run into the same scenario whenever I want to change a splitter to indexed values, and it feels lame to have to spend a few minutes re-patching. If I'm working quickly, and want to avoid repatching, I usually just have my virtual splitter sitting there, attached to everything....
Then I pull a splitter from the patch list, change it to whatever type it needs to be (I find myself doing this with index setups quite a bit), and then feed that to the virtual splitter. So, I might have two splitters in a row, but it doesn't seem to cause a perceivable hit, and it works 100%. It makes sure that no connections break, especially if you are in a hurry. I think your intuition about the multiplexer/upstream evaluation is probably what the original poster is running into. I am very thankful that the upstream stuff doesn't get evaluated in instances like this, that's for sure :) The "dud" renderer patch method seems to be handy for the rare times that it needs to be evaluating, but my thought is that if one needs that, the organization of the composition is likely not quite suited to QC's paradigm. -George Toledo On Fri, Jun 26, 2009 at 2:14 PM, Christopher Wright <[email protected]>wrote: > The conditional puts out boolean but the virtual multiplexer puts out a >> 1/0, not a true false on the output. One can hover on the input node, (using >> index 1, the boolean chain) of the virtual multiplexer and see a 1/0 instead >> of a true/false... so there is definitely type conversion happening right at >> the input of the virtual multiplexer, converting boolean to numeric. It's >> seems like it's not so hands off! :o) >> > > To your computer, "True" is 1 (or non-zero), "False" is 0. the word "true" > is 4 bytes (assuming you're using UTF-8 -- it's 8 bytes in UTF-16). In QC, > a Boolean Port does not store the words "True" or "False", it stores a > single BOOL value. > > @interface QCBooleanPort : QCPort > { > BOOL _value; <-- > True/False-ness stored Right here! :) > void *_unused3[4]; > } > - (BOOL)booleanValue; > - (void)setBooleanValue:(BOOL)fp8; > @end > > When you're mousing over a Boolean Port (the output of the conditional, for > example), it's calling this: > -[QCBooleanPort tooltipString];, which returns "Value: True" or > "Value: False" (based on the _value variable above). > > defined like this: > @interface QCBooleanPort (Tooltip) > - (id)tooltipString; > @end > > When you mouseover a Virtual port, it calls this: > -[QCVirtualPort tooltipString];, which interprets the _value > variable differently (I don't know the specifics, but it's a different > formatting, illustrated below) > > defined here: > > @interface QCVirtualPort (Tooltip) > - (id)tooltipString; > @end > > So while it's working on the same port value, it's actually using 2 > different methods to form the tooltip depending on which end you're looking > at. But either way, they're using the same data, and not modifying it. > > Here's some proof that it's happening: fire up GDB with QC, set a > breakpoint on -[QCBooleanPort tooltipString];, and on -[QCVirtualPort > tooltipString], like this: > (gdb) b -[QCBooleanPort tooltipString] > Breakpoint 1 at 0x984628 > (gdb) b -[QCVirtualPort tooltipString] > Breakpoint 2 at 0x985358 > > Start QC > (gdb) run > > Then run open your composition. mouse over each port. Note which > breakpoint trips depending on which end you're over (use the command "cont" > to continue past the breakpoint): > Breakpoint 1, 0x935c2628 in -[QCBooleanPort(Tooltip) tooltipString] > () > (gdb) cont > Continuing. > Breakpoint 2, 0x935c3358 in -[QCVirtualPort(Tooltip) tooltipString] > () > (gdb) cont > Continuing. > > Wow, same value, yet we can trip both break points depending on which end > point we use! And, the 2nd one doesn't fall back to the first one > (otherwise, we'd get a break on breakpoint 1 immediately afterwards). :) > > I would do some disassembly junk here, but it's long and boring, so > instead, try this: > > LFO -> Multiplexer -> sprite. Set timebase on LFO to external, set time to > 0.1 (so we get something more interesting than 0.5, but constant). > > > > > Where does all that extra precision come from on the virtual port? if it's > typecasting, it can't possibly add precision. We also get the word "Value" > for number ports, but "Description" for Virtual ports... so it looks like > there are other inconsistencies as well when it comes to virtual ports > generating descriptions. But type-conversions is not what it's doing. (and > besides, converting True to 1 to True doesn't actually require any work, and > doesn't lose any precision...) So what happens is that Number Ports > actually print less precision than their virtual port counterparts. You can > do this with javascript as well, to ensure that's it's not just roundoff > error. > > I promise you, QCVirtualPort doesn't modify the value in any way, even if > the values get printed in different formats sometimes. > > It's also important to note that Multiplexers DON'T execute upstream > patches for unused ports -- they only cause the patches upstream from their > requested Source Index to evaluate. (part of the whole lazy eval model). > This can also be a cause of apparently-stale values. > > QC isn't written in Javascript -- it uses real, honest-to-goodness types > that have real, honest-to-goodness well-defined behaviours. It's the > methods on top that can sometimes present stuff less clearly. > > I can see the argument that a boolean/numeric thing shouldn't break, but >> then that seems to leave functionality in an inconsistent state; there would >> basically be one exception to the rule. If I had something hooked up >> boolean, and published for a user, they have two options, and it will turn >> something on/off. If I change it to numeric without limiting the input >> splitter to 0/1, and having floating values available... now all of a sudden >> the user can do many things that create abnormal function. So... I think I >> lean towards the "noodle breaking". I can kind of see both sides of this >> one. Most the time it would be more convenient for me if it didn't break, >> but it can probably help prevent bad programming. >> > > > The problem with this then comes when you use a default splitter (which is > virtual), and you need to retype it for menus or whatever. So you change > it, and that breaks everything. I guess I should have refined my > break/don't break thoughts to include Virtual -> Anything else, where the > endpoints more or less match up, since that's really about the only case I > personally care about. > > -- > [ christopher wright ] > [email protected] > http://kineme.net/ > > >
_______________________________________________ Do not post admin requests to the list. They will be ignored. Quartzcomposer-dev mailing list ([email protected]) Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/quartzcomposer-dev/archive%40mail-archive.com This email sent to [email protected]

