diff options
author | Sean Dague | 2008-09-03 18:04:37 +0000 |
---|---|---|
committer | Sean Dague | 2008-09-03 18:04:37 +0000 |
commit | 12beaccec79319186ae2a7bf3663510584117a63 (patch) | |
tree | 0dadf7a61269ae5215d1c007a2c8b7749e84e434 /OpenSim/Region/Environment/Modules/ContentManagementSystem/CMModel.cs | |
parent | Update svn properties. (diff) | |
download | opensim-SC-12beaccec79319186ae2a7bf3663510584117a63.zip opensim-SC-12beaccec79319186ae2a7bf3663510584117a63.tar.gz opensim-SC-12beaccec79319186ae2a7bf3663510584117a63.tar.bz2 opensim-SC-12beaccec79319186ae2a7bf3663510584117a63.tar.xz |
Merge branch 'cms' of http://pokgsa.ibm.com/~jbongio/public/opensim
Diffstat (limited to 'OpenSim/Region/Environment/Modules/ContentManagementSystem/CMModel.cs')
-rw-r--r-- | OpenSim/Region/Environment/Modules/ContentManagementSystem/CMModel.cs | 309 |
1 files changed, 309 insertions, 0 deletions
diff --git a/OpenSim/Region/Environment/Modules/ContentManagementSystem/CMModel.cs b/OpenSim/Region/Environment/Modules/ContentManagementSystem/CMModel.cs new file mode 100644 index 0000000..d3b3b77 --- /dev/null +++ b/OpenSim/Region/Environment/Modules/ContentManagementSystem/CMModel.cs | |||
@@ -0,0 +1,309 @@ | |||
1 | // CMModel.cs | ||
2 | // User: bongiojp | ||
3 | // | ||
4 | // | ||
5 | |||
6 | using System; | ||
7 | using System.Collections.Generic; | ||
8 | using System.Collections; | ||
9 | using libsecondlife; | ||
10 | using OpenSim; | ||
11 | using OpenSim.Framework; | ||
12 | using OpenSim.Region.Environment.Interfaces; | ||
13 | using OpenSim.Region.Environment.Scenes; | ||
14 | using log4net; | ||
15 | using OpenSim.Region.Physics.Manager; | ||
16 | using Axiom.Math; | ||
17 | using System.Diagnostics; | ||
18 | |||
19 | namespace OpenSim.Region.Environment.Modules.ContentManagement | ||
20 | { | ||
21 | |||
22 | public class CMModel | ||
23 | { | ||
24 | static float TimeToUpdate = 0; | ||
25 | static float TimeToConvertXml = 0; | ||
26 | |||
27 | private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); | ||
28 | |||
29 | IContentDatabase m_database = null; | ||
30 | |||
31 | /// <value> | ||
32 | /// The class that contains all auras and metaentities used in the CMS. | ||
33 | /// </value> | ||
34 | CMEntityCollection m_MetaEntityCollection = new CMEntityCollection(); | ||
35 | |||
36 | public CMEntityCollection MetaEntityCollection | ||
37 | { | ||
38 | get { return m_MetaEntityCollection; } | ||
39 | } | ||
40 | |||
41 | public CMModel() | ||
42 | { | ||
43 | } | ||
44 | |||
45 | public void Initialise(string database) | ||
46 | { | ||
47 | if (database == "FileSystemDatabase") | ||
48 | m_database = new FileSystemDatabase(); | ||
49 | else if (database == "GitDatabase") | ||
50 | m_database = new GitDatabase(); | ||
51 | } | ||
52 | |||
53 | public void InitialiseDatabase(Scene scene, string dir) | ||
54 | { | ||
55 | m_database.Initialise(scene, dir); | ||
56 | } | ||
57 | |||
58 | /// <summary> | ||
59 | /// Should be called just once to finish initializing the database. | ||
60 | /// </summary> | ||
61 | public void PostInitialise() | ||
62 | { | ||
63 | m_database.PostInitialise(); | ||
64 | } | ||
65 | |||
66 | public ContentManagementEntity FindMetaEntityAffectedByUndo(LLUUID uuid) | ||
67 | { | ||
68 | ContentManagementEntity ent = GetMetaGroupByPrim(uuid); | ||
69 | return ent; | ||
70 | } | ||
71 | |||
72 | /// <summary> | ||
73 | /// Removes the green aura when an a new scene object group is deleted. | ||
74 | /// </summary> | ||
75 | public void RemoveOrUpdateDeletedEntity(SceneObjectGroup group) | ||
76 | { | ||
77 | // Deal with new parts not revisioned that have been deleted. | ||
78 | foreach(SceneObjectPart part in group.Children.Values) | ||
79 | if (m_MetaEntityCollection.Auras.ContainsKey(part.UUID)) | ||
80 | m_MetaEntityCollection.RemoveNewlyCreatedEntityAura(part.UUID); | ||
81 | } | ||
82 | |||
83 | /// <summary> | ||
84 | /// Uses the database to serialize all current scene objects into xml and save into a database with an accompanying log message. | ||
85 | /// </summary> | ||
86 | public void CommitRegion(Scene scene, String logMessage) | ||
87 | { | ||
88 | m_log.Debug("[CONTENT MANAG] saving " + scene.RegionInfo.RegionName + " with log message: " + logMessage + " length of message: " + logMessage.Length); | ||
89 | m_database.SaveRegion(scene.RegionInfo.RegionID, scene.RegionInfo.RegionName, logMessage); | ||
90 | m_log.Debug("[CONTENT MANAG] the region name we are dealing with heeeeeeeere: " + scene.RegionInfo.RegionName ); | ||
91 | } | ||
92 | |||
93 | /// <summary> | ||
94 | /// Retrieves the latest revision of a region in xml form, | ||
95 | /// converts it to scene object groups and scene presences, | ||
96 | /// swaps the current scene's entity list with the revision's list. | ||
97 | /// Note: Since deleted objects while | ||
98 | /// </summary> | ||
99 | public void RollbackRegion(Scene scene) | ||
100 | { | ||
101 | System.Collections.ArrayList xmllist = null; | ||
102 | SceneObjectGroup temp = null; | ||
103 | System.Collections.Hashtable deleteListUUIDs = new Hashtable(); | ||
104 | Dictionary<LLUUID, EntityBase> SearchList = new Dictionary<LLUUID,EntityBase>(); | ||
105 | Dictionary<LLUUID, EntityBase> ReplacementList = new Dictionary<LLUUID,EntityBase>(); | ||
106 | int revision = m_database.GetMostRecentRevision(scene.RegionInfo.RegionID); | ||
107 | EntityBase[] searchArray; | ||
108 | |||
109 | xmllist = m_database.GetRegionObjectXMLList(scene.RegionInfo.RegionID, revision); | ||
110 | if (xmllist == null) | ||
111 | { | ||
112 | m_log.Info("[CMMODEL]: Region (" + scene.RegionInfo.RegionID + ") does not have given revision number (" + revision + ")."); | ||
113 | return; | ||
114 | } | ||
115 | |||
116 | m_log.Info("[CMMODEL]: Region (" + scene.RegionInfo.RegionID + ") revision number (" + revision + ")."); | ||
117 | m_log.Info("[CMMODEL]: Scene Objects = " + xmllist.Count); | ||
118 | m_log.Info("[CMMODEL]: Converting scene entities list to specified revision."); | ||
119 | |||
120 | m_log.ErrorFormat("[CMMODEL]: 1"); | ||
121 | |||
122 | foreach (string xml in xmllist) | ||
123 | { | ||
124 | try{ | ||
125 | temp = new SceneObjectGroup(xml); | ||
126 | temp.SetScene(scene); | ||
127 | foreach(SceneObjectPart part in temp.Children.Values) | ||
128 | part.RegionHandle = scene.RegionInfo.RegionHandle; | ||
129 | ReplacementList.Add(temp.UUID, (EntityBase)temp); | ||
130 | } | ||
131 | catch(Exception e) | ||
132 | { | ||
133 | m_log.Info("[CMMODEL]: Error while creating replacement list for rollback: " + e); | ||
134 | } | ||
135 | } | ||
136 | |||
137 | //If in scene but not in revision and not a client, remove them | ||
138 | while (true) | ||
139 | { | ||
140 | try | ||
141 | { | ||
142 | foreach(EntityBase entity in scene.GetEntities()) | ||
143 | { | ||
144 | if (entity == null) | ||
145 | continue; | ||
146 | |||
147 | if (entity is ScenePresence) | ||
148 | { | ||
149 | ReplacementList.Add(entity.UUID, entity); | ||
150 | continue; | ||
151 | } | ||
152 | else //if (!ReplacementList.ContainsKey(entity.UUID)) | ||
153 | deleteListUUIDs.Add(entity.UUID, 0); | ||
154 | } | ||
155 | } | ||
156 | catch(Exception e) | ||
157 | { | ||
158 | m_log.ErrorFormat("[CMMODEL]: " + e); | ||
159 | deleteListUUIDs.Clear(); | ||
160 | ReplacementList.Clear(); | ||
161 | continue; | ||
162 | } | ||
163 | break; | ||
164 | } | ||
165 | |||
166 | foreach(LLUUID uuid in deleteListUUIDs.Keys) | ||
167 | { | ||
168 | try | ||
169 | { | ||
170 | // I thought that the DeleteGroup() function would handle all of this, but it doesn't. I'm not sure WHAT it handles. | ||
171 | ((SceneObjectGroup)scene.Entities[uuid]).DetachFromBackup((SceneObjectGroup)scene.Entities[uuid]); | ||
172 | scene.PhysicsScene.RemovePrim(((SceneObjectGroup)scene.Entities[uuid]).RootPart.PhysActor); | ||
173 | scene.SendKillObject(scene.Entities[uuid].LocalId); | ||
174 | scene.m_innerScene.DeleteSceneObject(uuid, false); | ||
175 | ((SceneObjectGroup)scene.Entities[uuid]).DeleteGroup(); | ||
176 | } | ||
177 | catch(Exception e) | ||
178 | { | ||
179 | m_log.ErrorFormat("[CMMODEL]: Error while removing objects from scene: " + e); | ||
180 | } | ||
181 | } | ||
182 | |||
183 | lock (scene) | ||
184 | { | ||
185 | scene.Entities = ReplacementList; | ||
186 | } | ||
187 | |||
188 | foreach(EntityBase ent in ReplacementList.Values) | ||
189 | { | ||
190 | try | ||
191 | { | ||
192 | if (!(ent is SceneObjectGroup)) | ||
193 | continue; | ||
194 | |||
195 | if ((((SceneObjectGroup)ent).RootPart.GetEffectiveObjectFlags() & (uint) LLObject.ObjectFlags.Phantom) == 0) | ||
196 | ((SceneObjectGroup)ent).ApplyPhysics(true); | ||
197 | ((SceneObjectGroup)ent).AttachToBackup(); | ||
198 | ((SceneObjectGroup)ent).HasGroupChanged = true; // If not true, then attaching to backup does nothing because no change is detected. | ||
199 | ((SceneObjectGroup)ent).ScheduleGroupForFullUpdate(); | ||
200 | } | ||
201 | catch(Exception e) | ||
202 | { | ||
203 | m_log.ErrorFormat("[CMMODEL]: Error while attaching new scene entities to backup and scheduling for a full update: " + e); | ||
204 | } | ||
205 | } | ||
206 | m_log.Info("[CMMODEL]: Scheduling a backup of new scene object groups to backup."); | ||
207 | scene.Backup(); | ||
208 | } | ||
209 | |||
210 | /// <summary> | ||
211 | /// Detects if a scene object group from the scene list has moved or changed scale. The green aura | ||
212 | /// that surrounds the object is then moved or scaled with the group. | ||
213 | /// </summary> | ||
214 | public System.Collections.ArrayList UpdateNormalEntityEffects(SceneObjectGroup group) | ||
215 | { | ||
216 | System.Collections.ArrayList auraList = new System.Collections.ArrayList(); | ||
217 | if (group == null) | ||
218 | return null; | ||
219 | foreach(SceneObjectPart part in group.Children.Values) | ||
220 | { | ||
221 | if (m_MetaEntityCollection.Auras.ContainsKey(part.UUID)) | ||
222 | { | ||
223 | ((AuraMetaEntity)m_MetaEntityCollection.Auras[part.UUID]).SetAura(new LLVector3(0,254,0), part.Scale); | ||
224 | ((AuraMetaEntity)m_MetaEntityCollection.Auras[part.UUID]).RootPart.GroupPosition = part.GetWorldPosition(); | ||
225 | auraList.Add((AuraMetaEntity)m_MetaEntityCollection.Auras[part.UUID]); | ||
226 | } | ||
227 | } | ||
228 | return auraList; | ||
229 | } | ||
230 | |||
231 | public void DeleteAllMetaObjects() | ||
232 | { | ||
233 | m_MetaEntityCollection.ClearAll(); | ||
234 | } | ||
235 | |||
236 | /// <summary> | ||
237 | /// Downloads the latest revision of the given scene and converts the xml file to CMEntities. After this method, the view can find the differences | ||
238 | /// and display the differences to clients. | ||
239 | /// </summary> | ||
240 | public void UpdateCMEntities(Scene scene) | ||
241 | { | ||
242 | Stopwatch x = new Stopwatch(); | ||
243 | x.Start(); | ||
244 | |||
245 | System.Collections.ArrayList xmllist = null; | ||
246 | m_log.Debug("[CONTENT MANAGEMENT] Retrieving object xml files for region: " + scene.RegionInfo.RegionID); | ||
247 | xmllist = m_database.GetRegionObjectXMLList(scene.RegionInfo.RegionID); | ||
248 | m_log.Info("[FSDB]: got list"); | ||
249 | if (xmllist == null) | ||
250 | return; | ||
251 | |||
252 | Stopwatch y = new Stopwatch(); | ||
253 | y.Start(); | ||
254 | foreach (string xml in xmllist) | ||
255 | m_MetaEntityCollection.CreateNewEntity(xml, scene); | ||
256 | y.Stop(); | ||
257 | TimeToConvertXml += y.ElapsedMilliseconds; | ||
258 | m_log.Info("[FileSystemDatabase] Time spent converting xml to metaentities for " + scene.RegionInfo.RegionName + ": " + y.ElapsedMilliseconds); | ||
259 | m_log.Info("[FileSystemDatabase] Time spent converting xml to metaentities so far: " + TimeToConvertXml); | ||
260 | |||
261 | m_log.Info("[FSDB]: checking for new scene object parts missing green auras and create the auras"); | ||
262 | CheckForNewEntitiesMissingAuras(scene); | ||
263 | |||
264 | x.Stop(); | ||
265 | TimeToUpdate += x.ElapsedMilliseconds; | ||
266 | m_log.Info("[FileSystemDatabase] Time spent Updating entity list for " + scene.RegionInfo.RegionName + ": " + x.ElapsedMilliseconds); | ||
267 | m_log.Info("[FileSystemDatabase] Time spent Updating so far: " + TimeToUpdate); | ||
268 | |||
269 | } | ||
270 | |||
271 | /// <summary> | ||
272 | /// Compares the scene's object group list to the list of meta entities. If there is an object group that does not have a corresponding meta entity | ||
273 | /// it is a new part that must have a green aura (for diff mode). | ||
274 | /// Returns list of ContentManagementEntities | ||
275 | /// </summary> | ||
276 | public ArrayList CheckForNewEntitiesMissingAuras(Scene scene) | ||
277 | { | ||
278 | ArrayList missingList = null; | ||
279 | ArrayList newList = new ArrayList(); | ||
280 | |||
281 | m_log.Debug("[CONTENT MANAGEMENT] Checking for new scene object parts in scene: " + scene.RegionInfo.RegionName); | ||
282 | |||
283 | //Check if the current scene has groups not included in the current list of MetaEntities | ||
284 | //If so, then the current scene's parts that are new should be marked green. | ||
285 | missingList = m_MetaEntityCollection.CheckForMissingEntities(scene.GetEntities()); | ||
286 | |||
287 | foreach(Object missingPart in missingList) | ||
288 | { | ||
289 | if (m_MetaEntityCollection.Auras.ContainsKey(((SceneObjectPart)missingPart).UUID)) | ||
290 | continue; | ||
291 | newList.Add(m_MetaEntityCollection.CreateAuraForNewlyCreatedEntity((SceneObjectPart)missingPart)); | ||
292 | } | ||
293 | m_log.Info("Number of missing objects found: " + newList.Count); | ||
294 | return newList; | ||
295 | } | ||
296 | |||
297 | //-------------------------------- HELPERS --------------------------------------------------------------------// | ||
298 | |||
299 | public ContentManagementEntity GetMetaGroupByPrim(LLUUID uuid) | ||
300 | { | ||
301 | foreach (Object ent in m_MetaEntityCollection.Entities.Values) | ||
302 | { | ||
303 | if (((ContentManagementEntity)ent).HasChildPrim(uuid)) | ||
304 | return (ContentManagementEntity)ent; | ||
305 | } | ||
306 | return null; | ||
307 | } | ||
308 | } | ||
309 | } \ No newline at end of file | ||