Host.cs 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. #region License
  2. /*
  3. ENet for C#
  4. Copyright (c) 2011 James F. Bellinger <jfb@zer7.com>
  5. Permission to use, copy, modify, and/or distribute this software for any
  6. purpose with or without fee is hereby granted, provided that the above
  7. copyright notice and this permission notice appear in all copies.
  8. THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  9. WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  10. MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
  11. ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  12. WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  13. ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  14. OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  15. */
  16. #endregion
  17. using System;
  18. namespace ENet
  19. {
  20. public sealed unsafe class Host : IDisposable
  21. {
  22. private Native.ENetHost* host;
  23. public Host(ushort port, int peerLimit):
  24. this(new Address { Port = port }, peerLimit)
  25. {
  26. }
  27. public Host(Address? address, int peerLimit):
  28. this(address, peerLimit, 0)
  29. {
  30. }
  31. public Host(Address? address, int peerLimit, int channelLimit):
  32. this(address, peerLimit, channelLimit, 0, 0)
  33. {
  34. }
  35. public Host(Address? address, int peerLimit, int channelLimit, uint incomingBandwidth, uint outgoingBandwidth)
  36. {
  37. if (this.host != null)
  38. {
  39. throw new InvalidOperationException("Already created.");
  40. }
  41. if (peerLimit < 0 || peerLimit > Native.ENET_PROTOCOL_MAXIMUM_PEER_ID)
  42. {
  43. throw new ArgumentOutOfRangeException("peerLimit");
  44. }
  45. CheckChannelLimit(channelLimit);
  46. if (address != null)
  47. {
  48. Native.ENetAddress nativeAddress = address.Value.NativeData;
  49. this.host = Native.enet_host_create(
  50. ref nativeAddress, (IntPtr)peerLimit, (IntPtr)channelLimit, incomingBandwidth,
  51. outgoingBandwidth);
  52. }
  53. else
  54. {
  55. this.host = Native.enet_host_create(
  56. null, (IntPtr)peerLimit, (IntPtr)channelLimit, incomingBandwidth,
  57. outgoingBandwidth);
  58. }
  59. if (this.host == null)
  60. {
  61. throw new ENetException(0, "Host creation call failed.");
  62. }
  63. }
  64. ~Host()
  65. {
  66. this.Dispose();
  67. }
  68. private static void CheckChannelLimit(int channelLimit)
  69. {
  70. if (channelLimit < 0 || channelLimit > Native.ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT)
  71. {
  72. throw new ArgumentOutOfRangeException("channelLimit");
  73. }
  74. }
  75. private void CheckCreated()
  76. {
  77. if (this.host == null)
  78. {
  79. throw new InvalidOperationException("Not created.");
  80. }
  81. }
  82. public void Dispose()
  83. {
  84. if (this.host == null)
  85. {
  86. return;
  87. }
  88. Native.enet_host_destroy(this.host);
  89. this.host = null;
  90. }
  91. public void Broadcast(byte channelID, ref Packet packet)
  92. {
  93. this.CheckCreated();
  94. packet.CheckCreated();
  95. Native.enet_host_broadcast(this.host, channelID, packet.NativeData);
  96. packet.NativeData = null; // Broadcast automatically clears this.
  97. }
  98. public void CompressWithRangeEncoder()
  99. {
  100. this.CheckCreated();
  101. Native.enet_host_compress_with_range_encoder(this.host);
  102. }
  103. public void DoNotCompress()
  104. {
  105. this.CheckCreated();
  106. Native.enet_host_compress(this.host, null);
  107. }
  108. public int CheckEvents(out Event e)
  109. {
  110. this.CheckCreated();
  111. Native.ENetEvent nativeEvent;
  112. int ret = Native.enet_host_check_events(this.host, out nativeEvent);
  113. e = new Event(nativeEvent);
  114. return ret;
  115. }
  116. public Peer Connect(Address address, int channelLimit, uint data)
  117. {
  118. this.CheckCreated();
  119. CheckChannelLimit(channelLimit);
  120. Native.ENetAddress nativeAddress = address.NativeData;
  121. Native.ENetPeer* p = Native.enet_host_connect(this.host, ref nativeAddress, (IntPtr) channelLimit, data);
  122. if (p == null)
  123. {
  124. throw new ENetException(0, "Host connect call failed.");
  125. }
  126. var peer = new Peer(p);
  127. return peer;
  128. }
  129. public void Flush()
  130. {
  131. this.CheckCreated();
  132. Native.enet_host_flush(this.host);
  133. }
  134. public int Service(int timeout)
  135. {
  136. if (timeout < 0)
  137. {
  138. throw new ArgumentOutOfRangeException("timeout");
  139. }
  140. this.CheckCreated();
  141. return Native.enet_host_service(this.host, null, (uint) timeout);
  142. }
  143. public int Service(int timeout, out Event e)
  144. {
  145. if (timeout < 0)
  146. {
  147. throw new ArgumentOutOfRangeException("timeout");
  148. }
  149. this.CheckCreated();
  150. Native.ENetEvent nativeEvent;
  151. int ret = Native.enet_host_service(this.host, out nativeEvent, (uint) timeout);
  152. e = new Event(nativeEvent);
  153. return ret;
  154. }
  155. public void SetBandwidthLimit(uint incomingBandwidth, uint outgoingBandwidth)
  156. {
  157. this.CheckCreated();
  158. Native.enet_host_bandwidth_limit(this.host, incomingBandwidth, outgoingBandwidth);
  159. }
  160. public void SetChannelLimit(int channelLimit)
  161. {
  162. CheckChannelLimit(channelLimit);
  163. this.CheckCreated();
  164. Native.enet_host_channel_limit(this.host, (IntPtr) channelLimit);
  165. }
  166. }
  167. }