opensim-development – Blame information for rev 1

Subversion Repositories:
Rev:
Rev Author Line No. Line
1 eva 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 using OpenMetaverse;
36  
37 namespace OpenSim.Region.Physics.Manager
38 {
39 /// <summary>
40 /// Description of MyClass.
41 /// </summary>
42 public class PhysicsPluginManager
43 {
44 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
45  
46 private Dictionary<string, IPhysicsPlugin> _PhysPlugins = new Dictionary<string, IPhysicsPlugin>();
47 private Dictionary<string, IMeshingPlugin> _MeshPlugins = new Dictionary<string, IMeshingPlugin>();
48  
49 /// <summary>
50 /// Constructor.
51 /// </summary>
52 public PhysicsPluginManager()
53 {
54 // Load "plugins", that are hard coded and not existing in form of an external lib, and hence always
55 // available
56 IMeshingPlugin plugHard;
57 plugHard = new ZeroMesherPlugin();
58 _MeshPlugins.Add(plugHard.GetName(), plugHard);
59  
60 m_log.Info("[PHYSICS]: Added meshing engine: " + plugHard.GetName());
61 }
62  
63 /// <summary>
64 /// Get a physics scene for the given physics engine and mesher.
65 /// </summary>
66 /// <param name="physEngineName"></param>
67 /// <param name="meshEngineName"></param>
68 /// <param name="config"></param>
69 /// <returns></returns>
70 public PhysicsScene GetPhysicsScene(string physEngineName, string meshEngineName,
71 IConfigSource config, string regionName, Vector3 regionExtent)
72 {
73 if (String.IsNullOrEmpty(physEngineName))
74 {
75 return PhysicsScene.Null;
76 }
77  
78 if (String.IsNullOrEmpty(meshEngineName))
79 {
80 return PhysicsScene.Null;
81 }
82  
83 IMesher meshEngine = null;
84 if (_MeshPlugins.ContainsKey(meshEngineName))
85 {
86 m_log.Info("[PHYSICS]: creating meshing engine " + meshEngineName);
87 meshEngine = _MeshPlugins[meshEngineName].GetMesher(config);
88 }
89 else
90 {
91 m_log.WarnFormat("[PHYSICS]: couldn't find meshingEngine: {0}", meshEngineName);
92 throw new ArgumentException(String.Format("couldn't find meshingEngine: {0}", meshEngineName));
93 }
94  
95 if (_PhysPlugins.ContainsKey(physEngineName))
96 {
97 m_log.Info("[PHYSICS]: creating " + physEngineName);
98 PhysicsScene result = _PhysPlugins[physEngineName].GetScene(regionName);
99 result.Initialise(meshEngine, config, regionExtent);
100 return result;
101 }
102 else
103 {
104 m_log.WarnFormat("[PHYSICS]: couldn't find physicsEngine: {0}", physEngineName);
105 throw new ArgumentException(String.Format("couldn't find physicsEngine: {0}", physEngineName));
106 }
107 }
108  
109 /// <summary>
110 /// Load all plugins in assemblies at the given path
111 /// </summary>
112 /// <param name="pluginsPath"></param>
113 public void LoadPluginsFromAssemblies(string assembliesPath)
114 {
115 // Walk all assemblies (DLLs effectively) and see if they are home
116 // of a plugin that is of interest for us
117 string[] pluginFiles = Directory.GetFiles(assembliesPath, "*.dll");
118  
119 for (int i = 0; i < pluginFiles.Length; i++)
120 {
121 LoadPluginsFromAssembly(pluginFiles[i]);
122 }
123 }
124  
125 /// <summary>
126 /// Load plugins from an assembly at the given path
127 /// </summary>
128 /// <param name="assemblyPath"></param>
129 public void LoadPluginsFromAssembly(string assemblyPath)
130 {
131 // TODO / NOTE
132 // The assembly named 'OpenSim.Region.Physics.BasicPhysicsPlugin' was loaded from
133 // 'file:///C:/OpenSim/trunk2/bin/Physics/OpenSim.Region.Physics.BasicPhysicsPlugin.dll'
134 // using the LoadFrom context. The use of this context can result in unexpected behavior
135 // for serialization, casting and dependency resolution. In almost all cases, it is recommended
136 // that the LoadFrom context be avoided. This can be done by installing assemblies in the
137 // Global Assembly Cache or in the ApplicationBase directory and using Assembly.
138 // Load when explicitly loading assemblies.
139 Assembly pluginAssembly = null;
140 Type[] types = null;
141  
142 try
143 {
144 pluginAssembly = Assembly.LoadFrom(assemblyPath);
145 }
146 catch (Exception ex)
147 {
148 m_log.Error("[PHYSICS]: Failed to load plugin from " + assemblyPath, ex);
149 }
150  
151 if (pluginAssembly != null)
152 {
153 try
154 {
155 types = pluginAssembly.GetTypes();
156 }
157 catch (ReflectionTypeLoadException ex)
158 {
159 m_log.Error("[PHYSICS]: Failed to enumerate types in plugin from " + assemblyPath + ": " +
160 ex.LoaderExceptions[0].Message, ex);
161 }
162 catch (Exception ex)
163 {
164 m_log.Error("[PHYSICS]: Failed to enumerate types in plugin from " + assemblyPath, ex);
165 }
166  
167 if (types != null)
168 {
169 foreach (Type pluginType in types)
170 {
171 if (pluginType.IsPublic)
172 {
173 if (!pluginType.IsAbstract)
174 {
175 Type physTypeInterface = pluginType.GetInterface("IPhysicsPlugin", true);
176  
177 if (physTypeInterface != null)
178 {
179 IPhysicsPlugin plug =
180 (IPhysicsPlugin)Activator.CreateInstance(pluginAssembly.GetType(pluginType.ToString()));
181 plug.Init();
182 if (!_PhysPlugins.ContainsKey(plug.GetName()))
183 {
184 _PhysPlugins.Add(plug.GetName(), plug);
185 m_log.Info("[PHYSICS]: Added physics engine: " + plug.GetName());
186 }
187 }
188  
189 Type meshTypeInterface = pluginType.GetInterface("IMeshingPlugin", true);
190  
191 if (meshTypeInterface != null)
192 {
193 IMeshingPlugin plug =
194 (IMeshingPlugin)Activator.CreateInstance(pluginAssembly.GetType(pluginType.ToString()));
195 if (!_MeshPlugins.ContainsKey(plug.GetName()))
196 {
197 _MeshPlugins.Add(plug.GetName(), plug);
198 m_log.Info("[PHYSICS]: Added meshing engine: " + plug.GetName());
199 }
200 }
201  
202 physTypeInterface = null;
203 meshTypeInterface = null;
204 }
205 }
206 }
207 }
208 }
209  
210 pluginAssembly = null;
211 }
212  
213 //---
214 public static void PhysicsPluginMessage(string message, bool isWarning)
215 {
216 if (isWarning)
217 {
218 m_log.Warn("[PHYSICS]: " + message);
219 }
220 else
221 {
222 m_log.Info("[PHYSICS]: " + message);
223 }
224 }
225  
226 //---
227 }
228  
229 public interface IPhysicsPlugin
230 {
231 bool Init();
232 PhysicsScene GetScene(String sceneIdentifier);
233 string GetName();
234 void Dispose();
235 }
236  
237 public interface IMeshingPlugin
238 {
239 string GetName();
240 IMesher GetMesher(IConfigSource config);
241 }
242 }