summaryrefslogtreecommitdiff
path: root/indra/newview/llmaterialmgr.h
blob: 8a2a9be255f8381104f3ee3b5a2a7968f737cc3c (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
133
134
135
136
/**
 * @file llmaterialmgr.h
 * @brief Material manager
 *
 * $LicenseInfo:firstyear=2006&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_LLMATERIALMGR_H
#define LL_LLMATERIALMGR_H

#include "llmaterial.h"
#include "llmaterialid.h"
#include "llsingleton.h"

#define USE_TE_SPECIFIC_REGISTRATION 1

class LLViewerRegion;

class LLMaterialMgr : public LLSingleton<LLMaterialMgr>
{
	friend class LLSingleton<LLMaterialMgr>;
protected:
	LLMaterialMgr();
	virtual ~LLMaterialMgr();

public:
	typedef std::map<LLMaterialID, LLMaterialPtr> material_map_t;

	typedef boost::signals2::signal<void (const LLMaterialID&, const LLMaterialPtr)> get_callback_t;
	const LLMaterialPtr         get(const LLUUID& region_id, const LLMaterialID& material_id);
	boost::signals2::connection get(const LLUUID& region_id, const LLMaterialID& material_id, get_callback_t::slot_type cb);

#if USE_TE_SPECIFIC_REGISTRATION
	typedef boost::signals2::signal<void (const LLMaterialID&, const LLMaterialPtr, U32 te)> get_callback_te_t;
	boost::signals2::connection getTE(const LLUUID& region_id, const LLMaterialID& material_id, U32 te, get_callback_te_t::slot_type cb);
#endif

	typedef boost::signals2::signal<void (const LLUUID&, const material_map_t&)> getall_callback_t;
	void                        getAll(const LLUUID& region_id);
	boost::signals2::connection getAll(const LLUUID& region_id, getall_callback_t::slot_type cb);
	void put(const LLUUID& object_id, const U8 te, const LLMaterial& material);
	void remove(const LLUUID& object_id, const U8 te);

protected:
	void clearGetQueues(const LLUUID& region_id);
	bool isGetPending(const LLUUID& region_id, const LLMaterialID& material_id) const;
	bool isGetAllPending(const LLUUID& region_id) const;
	void markGetPending(const LLUUID& region_id, const LLMaterialID& material_id);
	const LLMaterialPtr setMaterial(const LLUUID& region_id, const LLMaterialID& material_id, const LLSD& material_data);

	static void onIdle(void*);
	void processGetQueue();
	void onGetResponse(bool success, const LLSD& content, const LLUUID& region_id);
	void processGetAllQueue();
	void onGetAllResponse(bool success, const LLSD& content, const LLUUID& region_id);
	void processPutQueue();
	void onPutResponse(bool success, const LLSD& content);
	void onRegionRemoved(LLViewerRegion* regionp);

protected:
	typedef std::set<LLMaterialID> material_queue_t;
	typedef std::map<LLUUID, material_queue_t> get_queue_t;
	get_queue_t        mGetQueue;
	typedef std::pair<const LLUUID, LLMaterialID> pending_material_t;
	typedef std::map<const pending_material_t, F64> get_pending_map_t;
	get_pending_map_t  mGetPending;
	typedef std::map<LLMaterialID, get_callback_t*> get_callback_map_t;
	get_callback_map_t mGetCallbacks;

#if USE_TE_SPECIFIC_REGISTRATION
	// struct for TE-specific material ID query
	class TEMaterialPair
	{
	public:

		U32 te;
		LLMaterialID materialID;

		bool operator==(const TEMaterialPair& b) const { return (materialID == b.materialID) && (te == b.te); }
	};
	
	friend inline bool operator<(
		const LLMaterialMgr::TEMaterialPair& lhs,
		const LLMaterialMgr::TEMaterialPair& rhs)
	{
		return (lhs.te	< rhs.te) ? TRUE :
			(lhs.materialID < rhs.materialID);
	}

	struct TEMaterialPairHasher
	{
		enum { bucket_size = 8 };
		size_t operator()(const TEMaterialPair& key_value) const { return *((size_t*)key_value.materialID.get());  } // cheesy, but effective
		bool   operator()(const TEMaterialPair& left, const TEMaterialPair& right) const { return left < right; }
	};

	typedef boost::unordered_map<TEMaterialPair, get_callback_te_t*, TEMaterialPairHasher> get_callback_te_map_t;
	get_callback_te_map_t mGetTECallbacks;
#endif

	typedef std::set<LLUUID> getall_queue_t;
	getall_queue_t        mGetAllQueue;
	getall_queue_t        mGetAllRequested;
	typedef std::map<LLUUID, F64> getall_pending_map_t;
	getall_pending_map_t  mGetAllPending;
	typedef std::map<LLUUID, getall_callback_t*> getall_callback_map_t;
	getall_callback_map_t mGetAllCallbacks;

	typedef std::map<U8, LLMaterial> facematerial_map_t;
	typedef std::map<LLUUID, facematerial_map_t> put_queue_t;
	put_queue_t mPutQueue;

	material_map_t mMaterials;
};

#endif // LL_LLMATERIALMGR_H