_____  

From: opensource-dev-boun...@lists.secondlife.com
[mailto:opensource-dev-boun...@lists.secondlife.com] On Behalf Of Marine
Kelley
Sent: Monday, May 10 2010 09:24
To: opensource-dev@lists.secondlife.com
Subject: [opensource-dev] Cannot wear two different bodyparts at the
sametime



Hello all,

I have just filed a JIRA under Viewer 2.0.1 (although it shows for 2.0.0 as
well) at  <https://jira.secondlife.com/browse/VWR-19425>
https://jira.secondlife.com/browse/VWR-19425

In short, when you wear a new skin and a new hair at the same time (by
selecting both and pressing Wear), one of them is worn then removed, leaving
you with the default version and an error message. I have discovered this
when testing RLV 2.0 (and pulling my hair for days over it) which uses
outfits very extensively and that ability is crippled. But since it is also
present in the vanilla SL viewer 2.0, I don't see what I can do.

Have anyone encountered this problem ?

Marine


 
*waves*
 
There's a few JIRAs on it already I think (not all of them that exact same
issue but all having to do with a broken COF) and all the "fun" bugs that
come from that.
 
What happens in your specific case:
  1) I'd guess you're calling LLAppearanceMgr::addCOFItemLink twice in a row
        - both the currently worn hair and skin link are removed from
"Current Outfit"
        - you'll have two calls to link_inventory_item() with two different
ModifiedCOFCallback callbacks
  2) (let's say the skin link callback fires first)
        - it fires off LLAppearanceMgr::updateAppearanceFromCOF() which does
the whole LLWearableHoldingPattern dance
        - the old skin link was removed but there's a new one so you're set
for skin
        - the old hair link was removed but the new hair link hasn't been
created yet (or the viewer hasn't been notified of it yet)
        - when it gets to LLWearableHoldingPattern::checkMissingWearables()
it decides that since there is no hair link in COF it should just create one
from scratch and wear that
 
You probably got lucky too since there's another bug in wearing more than
one body part at the same time:
  - when the wearable gets recovered it creates a new item link for it in
"Current Outfit"
  - when both the original and the recovered wearable link complete you now
have two body parts of the same type listed under COF and you may get lucky
and end up with the one you want, or you may get the one you don't want the
next time you try to wear something
 
The easiest solution there was to simply change "checkMissingWearable()" to
first call a new "recoverExistingWearable()" which checks what's currently
worn and reuses that instead of creating a new default wearable.
 
So it goes:
  - if wearable type either should be always be present (=body part) or was
requested (=clothing) but wasn't resolved then:
      - iterate over what's currently worn on that wearable type and compare
the asset UUID
      - if it matches then you just grab the existing LLWearable* and put
that in mFoundList instead
      - or do nothing if a clothing layer was requested but isn't currently
worn
 
Which goes back to the far less annoying 1.23 behaviour (if you wear
something that can't have its asset fetched (or that times out) then you do
*not* change what's currently worn).
 
It still won't work perfect though because you'll still have two independent
callbacks firing and two LLWearableHoldingPattern instances:
  - extend LLAppearanceMgr::addCOFItemLink to take a callback as an extra
parameter
  - instead of creating its own callback have it use the one passed to it if
it's not null
 
That way you can go:
  LLPointer<LLInventoryCallback> cb = new LLUpdateAppearanceOnDestroy();
  LLAppearanceMgr::instance().addCOFItemLink(..., true, cb);
  LLAppearanceMgr::instance().addCOFItemLink(..., true, cb);
  LLAppearanceMgr::instance().addCOFItemLink(..., true, cb);
 
And you'll just have one single call to
LLAppearanceMgr::updateAppearanceFromCOF() no matter how many you add. One
thing to note is that there's code in addCOFItemLink that will make sure
that if you already have an item of that wearable type in COF then it'll
remove the old link to make sure that you don't end up with 2 body parts and
4 shirts listed so you'll need to do that filtering yourself because since
the new links don't exist yet that code doesn't end up actually doing
anything (and in 2.0.2 it needs fixing to still filter out body parts).
 
So for me it looks like (items is an array of LLViewerInventoryItem* to body
parts and clothing items):
  LLAppearanceMgr::filterWearableItems(items, X); // <- this one isn't
public by default so you'll have to change that
 
  LLPointer<LLInventoryCallback> cb = new LLUpdateAppearanceOnDestroy();
  for (LLInventoryModel::item_array_t::const_iterator itItem =
items.begin(); itItem != items.end(); ++itItem)
    LLAppearanceMgr::instance().addCOFItemLink(*itItem, true, cb);

(X will be 1 on 2.0.1 but 5 - probably subject to change but that seems to
be the current limit - on 2.0.2 since that has the code for multi-wearables
all in place now and for 2.0.2 filterWearableItems needs "fixing" to handle
body parts differently because it doesn't do that on its own)
 
That's still not the end of it though :(.
 
- I had to make LLWearableHoldingPattern a "fake singleton" (only allow one
of them to be running at any given time) in order to get rid of some of the
COF corruption or "wear this, then suddenly unwear and/or revert to
something from before"
- instead of LLAppearanceMgr::purgeCategory() followed by linkAll() I use a
new "syncCOF" which instead of doing a complete purge followed by a rebuild
it instead purges what isn't wanted, links what is wanted but isn't linked
and keeps what's wanted and already linked (primarily useful because it cuts
down on the time it takes for link creation callbacks to fire which
side-steps some bugs even if it's not going to be perfect in and by itself)
- since attachments get attached/detached as part of
LLWearableHoldingPattern you'll see some of them getting attached only to
just end up detached again a second later (and others will revert) because
it'll be working off of an outdated list that's no longer accurate (so the
LLAgentWearable::userAttachMultipleAttachments should be in
updateAppearanceOnCOF and not in LLWearableHoldingPattern::onAllComplete()
- put in "COF validation" to keep COF in sync with what's worn (recreate
links that aren't actually missing but are still deleted by
LLWearableHoldingPattern::clearCOFLinksForMissingWearables() to name one)
and get rid of duplicates or "left-overs" (from trying to wear more than one
at a time)
- fix wearing multiple items at the same time (instead of calling
"LLXXXBridge::performAction" X times - which is the default behaviour you
just do the workaround above and wear all items at the same time - or attach
them all at the same time). This fixes the behaviour you're seeing with
"Wear" in the official viewer (and what's causing "Attachment pending for
this spot" on attachments when "Wear"'ing)
- fix for what's worn reverting when switching from 2.0 to 1.23 back to 2.0
(aside from the edge case where only an attachment changes but no change in
wearables)
- fix for http://jira.secondlife.com/browse/VWR-18780 (summary of goes wrong
is in the comments) - on the surface it might seem to match what you're
running into but it actually has a very different cause and chain of events
so they're not duplicates
 
With all of that it seems to more or less be glitch-free (I haven't been
able to trigger any of the official viewer appearance related bugs anyway so
far) and the code holds up fairly well across LL code drops so far. Some of
the patches fix the same issue in different places, others complement each
other.
 
The appearance manager doesn't really handle attachments well though: you
can't use addCOFItemLink on those because you'll spam the user with
"attachment is pending for this point" (aside from forcing them to rebake
just for wearing an attachment) and RezMultipleAttachmentsFromInv has a bug
that will discard new messages if the current one hasn't finished processing
yet. You can't use RezSingleAttachmentFromInv either because there's a time
delay between the time where it attaches and where the link will appear in
COF which causes it to get detached right after getting attached (although
it *usually* works well enough and certainly a whole lot better than using
COF to attach things).
 
I'd guess it was tested by dutifully clicking one single thing at a time and
then sitting and waiting for that to finish before wearing something new. It
breaks once you deviate from that or if the region you're on is experiencing
issue (stuck pending.downloads come to mind), or if the grid as a whole
isn't feeling well, or if your own internet is having hick-ups.
 
Since links are constantly getting deleted and created there's a chance
you'll run into inventory cache "corruption" too (you'll see - usually older
- items in COF that can't be deleted and when you look at the properties
they'll list as being owned by Thrax Linden - which is the default name in
the .xml for that panel). About all you can do then is just clear cache and
relog again.
 
I definitely symphatize with you :(. I've screamed at COF and the appearance
manager quite a LOT over the past 2 months :p. All in all it's rather
depressing since it takes time away from working on your own thing :(.
(And the frustration probably makes this email come out a lot more
"snarky"/"annoyed" then I'd want to)
 
I just redid my patches for 2.0.2 this weekend but I should still have the
2.0.1 ones somewhere if they'd be useful (for reference if nothing else).
Don't remember how commented they are, but with the outlines from this email
it should be okies. They're more or less limited to one issue per patch too
so it's not a 600Kb dump to sort through for those handful of lines that are
relevant :p.
 
(This really does need fixing in the offical viewer though)
 
Kitty
_______________________________________________
Policies and (un)subscribe information available here:
http://wiki.secondlife.com/wiki/OpenSource-Dev
Please read the policies before posting to keep unmoderated posting privileges

Reply via email to