clockwerk-opensim-stable – Blame information for rev 1

Subversion Repositories:
Rev:
Rev Author Line No. Line
1 vero 1 /*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27  
28 using System;
29 using System.Collections.Generic;
30 using System.IO;
31 using System.Reflection;
32 using Nini.Config;
33 using log4net;
34 using OpenSim.Framework;
35  
36 namespace OpenSim.Region.Physics.Manager
37 {
38 /// <summary>
39 /// Description of MyClass.
40 /// </summary>
41 public class PhysicsPluginManager
42 {
43 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
44  
45 private Dictionary<string, IPhysicsPlugin> _PhysPlugins = new Dictionary<string, IPhysicsPlugin>();
46 private Dictionary<string, IMeshingPlugin> _MeshPlugins = new Dictionary<string, IMeshingPlugin>();
47  
48 /// <summary>
49 /// Constructor.
50 /// </summary>
51 public PhysicsPluginManager()
52 {
53 // Load "plugins", that are hard coded and not existing in form of an external lib, and hence always
54 // available
55 IMeshingPlugin plugHard;
56 plugHard = new ZeroMesherPlugin();
57 _MeshPlugins.Add(plugHard.GetName(), plugHard);
58  
59 m_log.Info("[PHYSICS]: Added meshing engine: " + plugHard.GetName());
60 }
61  
62 /// <summary>
63 /// Get a physics scene for the given physics engine and mesher.
64 /// </summary>
65 /// <param name="physEngineName"></param>
66 /// <param name="meshEngineName"></param>
67 /// <param name="config"></param>
68 /// <returns></returns>
69 public PhysicsScene GetPhysicsScene(string physEngineName, string meshEngineName, IConfigSource config, string regionName)
70 {
71 if (String.IsNullOrEmpty(physEngineName))
72 {
73 return PhysicsScene.Null;
74 }
75  
76 if (String.IsNullOrEmpty(meshEngineName))
77 {
78 return PhysicsScene.Null;
79 }
80  
81 IMesher meshEngine = null;
82 if (_MeshPlugins.ContainsKey(meshEngineName))
83 {
84 m_log.Info("[PHYSICS]: creating meshing engine " + meshEngineName);
85 meshEngine = _MeshPlugins[meshEngineName].GetMesher(config);
86 }
87 else
88 {
89 m_log.WarnFormat("[PHYSICS]: couldn't find meshingEngine: {0}", meshEngineName);
90 throw new ArgumentException(String.Format("couldn't find meshingEngine: {0}", meshEngineName));
91 }
92  
93 if (_PhysPlugins.ContainsKey(physEngineName))
94 {
95 m_log.Info("[PHYSICS]: creating " + physEngineName);
96 PhysicsScene result = _PhysPlugins[physEngineName].GetScene(regionName);
97 result.Initialise(meshEngine, config);
98 return result;
99 }
100 else
101 {
102 m_log.WarnFormat("[PHYSICS]: couldn't find physicsEngine: {0}", physEngineName);
103 throw new ArgumentException(String.Format("couldn't find physicsEngine: {0}", physEngineName));
104 }
105 }
106  
107 /// <summary>
108 /// Load all plugins in assemblies at the given path
109 /// </summary>
110 /// <param name="pluginsPath"></param>
111 public void LoadPluginsFromAssemblies(string assembliesPath)
112 {
113 // Walk all assemblies (DLLs effectively) and see if they are home
114 // of a plugin that is of interest for us
115 string[] pluginFiles = Directory.GetFiles(assembliesPath, "*.dll");
116  
117 for (int i = 0; i < pluginFiles.Length; i++)
118 {
119 LoadPluginsFromAssembly(pluginFiles[i]);
120 }
121 }
122  
123 /// <summary>
124 /// Load plugins from an assembly at the given path
125 /// </summary>
126 /// <param name="assemblyPath"></param>
127 public void LoadPluginsFromAssembly(string assemblyPath)
128 {
129 // TODO / NOTE
130 // The assembly named 'OpenSim.Region.Physics.BasicPhysicsPlugin' was loaded from
131 // 'file:///C:/OpenSim/trunk2/bin/Physics/OpenSim.Region.Physics.BasicPhysicsPlugin.dll'
132 // using the LoadFrom context. The use of this context can result in unexpected behavior
133 // for serialization, casting and dependency resolution. In almost all cases, it is recommended
134 // that the LoadFrom context be avoided. This can be done by installing assemblies in the
135 // Global Assembly Cache or in the ApplicationBase directory and using Assembly.
136 // Load when explicitly loading assemblies.
137 Assembly pluginAssembly = null;
138 Type[] types = null;
139  
140 try
141 {
142 pluginAssembly = Assembly.LoadFrom(assemblyPath);
143 }
144 catch (Exception ex)
145 {
146 m_log.Error("[PHYSICS]: Failed to load plugin from " + assemblyPath, ex);
147 }
148  
149 if (pluginAssembly != null)
150 {
151 try
152 {
153 types = pluginAssembly.GetTypes();
154 }
155 catch (ReflectionTypeLoadException ex)
156 {
157 m_log.Error("[PHYSICS]: Failed to enumerate types in plugin from " + assemblyPath + ": " +
158 ex.LoaderExceptions[0].Message, ex);
159 }
160 catch (Exception ex)
161 {
162 m_log.Error("[PHYSICS]: Failed to enumerate types in plugin from " + assemblyPath, ex);
163 }
164  
165 if (types != null)
166 {
167 foreach (Type pluginType in types)
168 {
169 if (pluginType.IsPublic)
170 {
171 if (!pluginType.IsAbstract)
172 {
173 Type physTypeInterface = pluginType.GetInterface("IPhysicsPlugin", true);
174  
175 if (physTypeInterface != null)
176 {
177 IPhysicsPlugin plug =
178 (IPhysicsPlugin)Activator.CreateInstance(pluginAssembly.GetType(pluginType.ToString()));
179 plug.Init();
180 if (!_PhysPlugins.ContainsKey(plug.GetName()))
181 {
182 _PhysPlugins.Add(plug.GetName(), plug);
183 m_log.Info("[PHYSICS]: Added physics engine: " + plug.GetName());
184 }
185 }
186  
187 Type meshTypeInterface = pluginType.GetInterface("IMeshingPlugin", true);
188  
189 if (meshTypeInterface != null)
190 {
191 IMeshingPlugin plug =
192 (IMeshingPlugin)Activator.CreateInstance(pluginAssembly.GetType(pluginType.ToString()));
193 if (!_MeshPlugins.ContainsKey(plug.GetName()))
194 {
195 _MeshPlugins.Add(plug.GetName(), plug);
196 m_log.Info("[PHYSICS]: Added meshing engine: " + plug.GetName());
197 }
198 }
199  
200 physTypeInterface = null;
201 meshTypeInterface = null;
202 }
203 }
204 }
205 }
206 }
207  
208 pluginAssembly = null;
209 }
210  
211 //---
212 public static void PhysicsPluginMessage(string message, bool isWarning)
213 {
214 if (isWarning)
215 {
216 m_log.Warn("[PHYSICS]: " + message);
217 }
218 else
219 {
220 m_log.Info("[PHYSICS]: " + message);
221 }
222 }
223  
224 //---
225 }
226  
227 public interface IPhysicsPlugin
228 {
229 bool Init();
230 PhysicsScene GetScene(String sceneIdentifier);
231 string GetName();
232 void Dispose();
233 }
234  
235 public interface IMeshingPlugin
236 {
237 string GetName();
238 IMesher GetMesher(IConfigSource config);
239 }
240 }