summaryrefslogtreecommitdiff
path: root/indra/newview/llattachmentsmgr.h
blob: 2428acfb381d05c5914c12935b0efe3b763bd7f5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
/**
 * @file llattachmentsmgr.h
 * @brief Batches up attachment requests and sends them all
 * in one message.
 *
 * $LicenseInfo:firstyear=2004&license=viewerlgpl$
 * Second Life Viewer Source Code
 * Copyright (C) 2010, Linden Research, Inc.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation;
 * version 2.1 of the License only.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 *
 * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
 * $/LicenseInfo$
 */

#ifndef LL_LLATTACHMENTSMGR_H
#define LL_LLATTACHMENTSMGR_H

#include "llsingleton.h"

//--------------------------------------------------------------------------------
// LLAttachmentsMgr
//
// This class manages batching up of requests at two stages of
// attachment rezzing.
//
// First, attachments requested to rez get saved in
// mPendingAttachments and sent as a single
// RezMultipleAttachmentsFromInv request. This batching is needed
// mainly because of weaknessing the UI element->inventory item
// handling, such that we don't always know when we are requesting
// multiple items. Now they just pile up and get swept into a single
// request during the idle loop.
//
// Second, after attachments arrive, we need to generate COF links for
// them. There are both efficiency and UI correctness reasons why it
// is better to request all the COF links at once and run a single
// callback after they all complete. Given the vagaries of the
// attachment system, there is no guarantee that we will get all the
// attachments we ask for, but we frequently do. So in the common case
// that all the desired attachments arrive fairly quickly, we generate
// a single batched request for COF links. If attachments arrive late
// or not at all, we will still issue COF link requests once a timeout
// value has been exceeded.
//
// To handle attachments that never arrive, we forget about requests
// that exceed a timeout value.
//--------------------------------------------------------------------------------
class LLAttachmentsMgr: public LLSingleton<LLAttachmentsMgr>
{
    LLSINGLETON(LLAttachmentsMgr);
    virtual ~LLAttachmentsMgr();

public:
    // Stores info for attachments that will be requested during idle.
    struct AttachmentsInfo
    {
        LLUUID mItemID;
        U8 mAttachmentPt;
        bool mAdd;
    };
    typedef std::deque<AttachmentsInfo> attachments_vec_t;

    void addAttachmentRequest(const LLUUID& item_id,
                              const U8 attachment_pt,
                              const bool add);
    void onAttachmentRequested(const LLUUID& item_id);
    void requestAttachments(attachments_vec_t& attachment_requests);
    static void onIdle(void *);

    void onAttachmentArrived(const LLUUID& inv_item_id);

    void onDetachRequested(const LLUUID& inv_item_id);
    void onDetachCompleted(const LLUUID& inv_item_id);

    bool isAttachmentStateComplete() const;

private:

    class LLItemRequestTimes: public std::map<LLUUID,LLTimer>
    {
    public:
        LLItemRequestTimes(const std::string& op_name, F32 timeout);
        void addTime(const LLUUID& inv_item_id);
        void removeTime(const LLUUID& inv_item_id);
        bool wasRequestedRecently(const LLUUID& item_id) const;
        bool getTime(const LLUUID& inv_item_id, LLTimer& timer) const;

    private:
        F32 mTimeout;
        std::string mOpName;
    };

    void removeAttachmentRequestTime(const LLUUID& inv_item_id);
    void onIdle();
    void requestPendingAttachments();
    void linkRecentlyArrivedAttachments();
    void expireOldAttachmentRequests();
    void expireOldDetachRequests();
    void checkInvalidCOFLinks();
    void spamStatusInfo();

    // Attachments that we are planning to rez but haven't requested from the server yet.
    attachments_vec_t mPendingAttachments;

    // Attachments that have been requested from server but have not arrived yet.
    LLItemRequestTimes mAttachmentRequests;

    // Attachments that have been requested to detach but have not gone away yet.
    LLItemRequestTimes mDetachRequests;

    // Attachments that have arrived but have not been linked in the COF yet.
    std::set<LLUUID> mRecentlyArrivedAttachments;
    LLTimer mCOFLinkBatchTimer;

    // Attachments that are linked in the COF but may be invalid.
    LLItemRequestTimes mQuestionableCOFLinks;
};

#endif