aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Environment/Modules/Communications
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/Environment/Modules/Communications')
-rw-r--r--OpenSim/Region/Environment/Modules/Communications/Interregion/IInterregionModule.cs14
-rw-r--r--OpenSim/Region/Environment/Modules/Communications/Interregion/InterregionModule.cs161
-rw-r--r--OpenSim/Region/Environment/Modules/Communications/Interregion/RemotingObject.cs50
3 files changed, 225 insertions, 0 deletions
diff --git a/OpenSim/Region/Environment/Modules/Communications/Interregion/IInterregionModule.cs b/OpenSim/Region/Environment/Modules/Communications/Interregion/IInterregionModule.cs
new file mode 100644
index 0000000..c15738c
--- /dev/null
+++ b/OpenSim/Region/Environment/Modules/Communications/Interregion/IInterregionModule.cs
@@ -0,0 +1,14 @@
1using OpenSim.Framework;
2using OpenSim.Region.Environment.Scenes;
3
4namespace OpenSim.Region.Environment.Modules.Communications.Interregion
5{
6 public interface IInterregionModule
7 {
8 void RegisterMethod<T>(T e);
9 bool HasInterface<T>(Location loc);
10 T RequestInterface<T>(Location loc);
11 T[] RequestInterface<T>();
12 Location GetLocationByDirection(Scene scene, InterregionModule.Direction dir);
13 }
14} \ No newline at end of file
diff --git a/OpenSim/Region/Environment/Modules/Communications/Interregion/InterregionModule.cs b/OpenSim/Region/Environment/Modules/Communications/Interregion/InterregionModule.cs
new file mode 100644
index 0000000..858f099
--- /dev/null
+++ b/OpenSim/Region/Environment/Modules/Communications/Interregion/InterregionModule.cs
@@ -0,0 +1,161 @@
1using System;
2using System.Collections.Generic;
3using System.Runtime.Remoting;
4using System.Runtime.Remoting.Channels;
5using System.Runtime.Remoting.Channels.Tcp;
6using Nini.Config;
7using OpenSim.Framework;
8using OpenSim.Region.Environment.Interfaces;
9using OpenSim.Region.Environment.Scenes;
10
11namespace OpenSim.Region.Environment.Modules.Communications.Interregion
12{
13 public class InterregionModule : IInterregionModule, IRegionModule
14 {
15 #region Direction enum
16
17 public enum Direction
18 {
19 North,
20 NorthEast,
21 East,
22 SouthEast,
23 South,
24 SouthWest,
25 West,
26 NorthWest
27 }
28
29 #endregion
30
31 private readonly Dictionary<Type, Object> m_interfaces = new Dictionary<Type, object>();
32 private readonly List<Location> m_myLocations = new List<Location>();
33
34 private readonly Dictionary<Location, string[]> m_neighbourInterfaces = new Dictionary<Location, string[]>();
35 private readonly Dictionary<Location, RemotingObject> m_neighbourRemote = new Dictionary<Location, RemotingObject>();
36 private IConfigSource m_config;
37 private RemotingObject m_myRemote;
38
39 private TcpChannel m_tcpChannel;
40 private int m_tcpPort = 10101;
41
42 #region IRegionModule Members
43
44 public void Initialise(Scene scene, IConfigSource source)
45 {
46 m_myLocations.Add(new Location((int) scene.RegionInfo.RegionLocX,
47 (int) scene.RegionInfo.RegionLocY));
48 m_config = source;
49
50 scene.RegisterModuleInterface<IInterregionModule>(this);
51 }
52
53 //TODO: This prevents us from registering new scenes after PostInitialise if we want comms updated.
54 public void PostInitialise()
55 {
56 try
57 {
58 m_tcpPort = m_config.Configs["Comms"].GetInt("remoting_port", m_tcpPort);
59 }
60 catch
61 {
62 }
63
64 CreateRemotingObjects();
65 }
66
67 public void Close()
68 {
69 ChannelServices.UnregisterChannel(m_tcpChannel);
70 }
71
72 public string Name
73 {
74 get { return "InterregionModule"; }
75 }
76
77 public bool IsSharedModule
78 {
79 get { return true; }
80 }
81
82 #endregion
83
84 private void CreateRemotingObjects()
85 {
86 m_myRemote = new RemotingObject(m_interfaces, m_myLocations.ToArray());
87 m_tcpChannel = new TcpChannel(m_tcpPort);
88
89 ChannelServices.RegisterChannel(m_tcpChannel, false);
90 RemotingServices.Marshal(m_myRemote, "OpenSimRemote2", typeof (RemotingObject));
91 }
92
93 public void RegisterRemoteRegion(string uri)
94 {
95 RegisterRemotingInterface((RemotingObject) Activator.GetObject(typeof (RemotingObject), uri));
96 }
97
98 private void RegisterRemotingInterface(RemotingObject remote)
99 {
100 Location[] locs = remote.GetLocations();
101 string[] interfaces = remote.GetInterfaces();
102 foreach (Location loc in locs)
103 {
104 m_neighbourInterfaces[loc] = interfaces;
105 m_neighbourRemote[loc] = remote;
106 }
107 }
108
109 public void RegisterMethod<T>(T e)
110 {
111 m_interfaces[typeof (T)] = e;
112 }
113
114 public bool HasInterface<T>(Location loc)
115 {
116 foreach (string val in m_neighbourInterfaces[loc])
117 {
118 if (val == typeof (T).FullName)
119 {
120 return true;
121 }
122 }
123 return false;
124 }
125
126 public T RequestInterface<T>(Location loc)
127 {
128 if (m_neighbourRemote.ContainsKey(loc))
129 {
130 return m_neighbourRemote[loc].RequestInterface<T>();
131 }
132 else
133 {
134 throw new IndexOutOfRangeException("No neighbour availible at that location");
135 }
136 }
137
138 public T[] RequestInterface<T>()
139 {
140 List<T> m_t = new List<T>();
141 foreach (RemotingObject remote in m_neighbourRemote.Values)
142 {
143 try
144 {
145 m_t.Add(remote.RequestInterface<T>());
146 }
147 catch (NotSupportedException)
148 {
149 }
150 }
151 return m_t.ToArray();
152 }
153
154 public Location GetLocationByDirection(Scene scene, Direction dir)
155 {
156 return new Location(0, 0);
157 }
158
159 //TODO: This prevents us from registering new scenes after PostInitialise if we want comms updated.
160 }
161} \ No newline at end of file
diff --git a/OpenSim/Region/Environment/Modules/Communications/Interregion/RemotingObject.cs b/OpenSim/Region/Environment/Modules/Communications/Interregion/RemotingObject.cs
new file mode 100644
index 0000000..a735677
--- /dev/null
+++ b/OpenSim/Region/Environment/Modules/Communications/Interregion/RemotingObject.cs
@@ -0,0 +1,50 @@
1using System;
2using System.Collections.Generic;
3using OpenSim.Framework;
4
5namespace OpenSim.Region.Environment.Modules.Communications.Interregion
6{
7 public class RemotingObject : MarshalByRefObject
8 {
9 private readonly Location[] m_coords;
10 private readonly Dictionary<Type, Object> m_interfaces = new Dictionary<Type, object>();
11
12 public RemotingObject(Dictionary<Type, Object> myInterfaces, Location[] coords)
13 {
14 m_interfaces = myInterfaces;
15 m_coords = coords;
16 }
17
18 public Location[] GetLocations()
19 {
20 return (Location[]) m_coords.Clone();
21 }
22
23 public string[] GetInterfaces()
24 {
25 string[] interfaces = new string[m_interfaces.Count];
26 int i = 0;
27
28 foreach (KeyValuePair<Type, object> pair in m_interfaces)
29 {
30 interfaces[i++] = pair.Key.FullName;
31 }
32
33 return interfaces;
34 }
35
36 /// <summary>
37 /// Returns a registered interface availible to neighbouring regions.
38 /// </summary>
39 /// <typeparam name="T">The type of interface you wish to request</typeparam>
40 /// <returns>A MarshalByRefObject inherited from this region inheriting the interface requested.</returns>
41 /// <remarks>All registered interfaces <b>MUST</b> inherit from MarshalByRefObject and use only serialisable types.</remarks>
42 public T RequestInterface<T>()
43 {
44 if (m_interfaces.ContainsKey(typeof (T)))
45 return (T) m_interfaces[typeof (T)];
46
47 throw new NotSupportedException("No such interface registered.");
48 }
49 }
50} \ No newline at end of file