InterregionModule.cs 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Runtime.Remoting;
  4. using System.Runtime.Remoting.Channels;
  5. using System.Runtime.Remoting.Channels.Tcp;
  6. using Nini.Config;
  7. using OpenSim.Framework;
  8. using OpenSim.Region.Environment.Interfaces;
  9. using OpenSim.Region.Environment.Scenes;
  10. namespace OpenSim.Region.Environment.Modules.Grid.Interregion
  11. {
  12. public class InterregionModule : IInterregionModule, IRegionModule
  13. {
  14. #region Direction enum
  15. public enum Direction
  16. {
  17. North,
  18. NorthEast,
  19. East,
  20. SouthEast,
  21. South,
  22. SouthWest,
  23. West,
  24. NorthWest
  25. }
  26. #endregion
  27. private readonly Dictionary<Type, Object> m_interfaces = new Dictionary<Type, object>();
  28. private readonly List<Location> m_myLocations = new List<Location>();
  29. private readonly Dictionary<Location, string[]> m_neighbourInterfaces = new Dictionary<Location, string[]>();
  30. private readonly Dictionary<Location, RemotingObject> m_neighbourRemote = new Dictionary<Location, RemotingObject>();
  31. private IConfigSource m_config;
  32. private bool m_enabled = false;
  33. private Object m_lockObject = new object();
  34. private RemotingObject m_myRemote;
  35. private TcpChannel m_tcpChannel;
  36. private int m_tcpPort = 10101;
  37. #region IInterregionModule Members
  38. public void internal_CreateRemotingObjects()
  39. {
  40. lock (m_lockObject)
  41. {
  42. if (m_tcpChannel == null)
  43. {
  44. m_myRemote = new RemotingObject(m_interfaces, m_myLocations.ToArray());
  45. m_tcpChannel = new TcpChannel(m_tcpPort);
  46. ChannelServices.RegisterChannel(m_tcpChannel, false);
  47. RemotingServices.Marshal(m_myRemote, "OpenSimRemote2", typeof (RemotingObject));
  48. }
  49. }
  50. }
  51. public void RegisterMethod<T>(T e)
  52. {
  53. m_interfaces[typeof (T)] = e;
  54. }
  55. public bool HasInterface<T>(Location loc)
  56. {
  57. foreach (string val in m_neighbourInterfaces[loc])
  58. {
  59. if (val == typeof (T).FullName)
  60. {
  61. return true;
  62. }
  63. }
  64. return false;
  65. }
  66. public T RequestInterface<T>(Location loc)
  67. {
  68. if (m_neighbourRemote.ContainsKey(loc))
  69. {
  70. return m_neighbourRemote[loc].RequestInterface<T>();
  71. }
  72. else
  73. {
  74. throw new IndexOutOfRangeException("No neighbour availible at that location");
  75. }
  76. }
  77. public T[] RequestInterface<T>()
  78. {
  79. List<T> m_t = new List<T>();
  80. foreach (RemotingObject remote in m_neighbourRemote.Values)
  81. {
  82. try
  83. {
  84. m_t.Add(remote.RequestInterface<T>());
  85. }
  86. catch (NotSupportedException)
  87. {
  88. }
  89. }
  90. return m_t.ToArray();
  91. }
  92. public Location GetLocationByDirection(Scene scene, Direction dir)
  93. {
  94. return new Location(0, 0);
  95. }
  96. #endregion
  97. //TODO: This prevents us from registering new scenes after PostInitialise if we want comms updated.
  98. #region IRegionModule Members
  99. public void Initialise(Scene scene, IConfigSource source)
  100. {
  101. if (m_enabled)
  102. {
  103. m_myLocations.Add(new Location((int) scene.RegionInfo.RegionLocX,
  104. (int) scene.RegionInfo.RegionLocY));
  105. m_config = source;
  106. scene.RegisterModuleInterface<IInterregionModule>(this);
  107. }
  108. }
  109. //TODO: This prevents us from registering new scenes after PostInitialise if we want comms updated.
  110. public void PostInitialise()
  111. {
  112. if (m_enabled)
  113. {
  114. try
  115. {
  116. m_tcpPort = m_config.Configs["Comms"].GetInt("remoting_port", m_tcpPort);
  117. }
  118. catch
  119. {
  120. }
  121. internal_CreateRemotingObjects();
  122. }
  123. }
  124. public void Close()
  125. {
  126. ChannelServices.UnregisterChannel(m_tcpChannel);
  127. }
  128. public string Name
  129. {
  130. get { return "InterregionModule"; }
  131. }
  132. public bool IsSharedModule
  133. {
  134. get { return true; }
  135. }
  136. #endregion
  137. public void RegisterRemoteRegion(string uri)
  138. {
  139. RegisterRemotingInterface((RemotingObject) Activator.GetObject(typeof (RemotingObject), uri));
  140. }
  141. private void RegisterRemotingInterface(RemotingObject remote)
  142. {
  143. Location[] locs = remote.GetLocations();
  144. string[] interfaces = remote.GetInterfaces();
  145. foreach (Location loc in locs)
  146. {
  147. m_neighbourInterfaces[loc] = interfaces;
  148. m_neighbourRemote[loc] = remote;
  149. }
  150. }
  151. }
  152. }