Browse Source

Changed host:get_peer() and added more wrappers

host:get_peer(index) now returns the specific peer at a given index and
not the n-th connected peer.

removed functions:
  host:connected_peer_count() (can be done manually)

added functions:
  host:compress_with_range_coder()
  peer:index()
	peer:state()
	peer:connect_id()

Conflicts:

	docs/index.md
Martin Felis 12 năm trước cách đây
mục cha
commit
57ed362ef1
2 tập tin đã thay đổi với 177 bổ sung82 xóa
  1. 65 45
      docs/index.md
  2. 112 37
      enet.c

+ 65 - 45
docs/index.md

@@ -8,6 +8,8 @@ To get an idea of how ENet works and what it provides have a look at
 [Features and Achritecture](http://enet.bespin.org/Features.html) from the
 original documentation.
 
+[TOC]
+
 <a name="install"></a>
 ## Download & Install
 
@@ -142,6 +144,10 @@ data received.
 Checks for any queued events and dispatches one if available. Returns the
 associated event if something was dispatched, otherwise `nil`.
 
+### `host:compress_with_range_coder()`
+Enables an adaptive order-2 PPM range coder for the transmitted data of
+all pers.
+
 ### `host:flush()`
 Sends any queued packets. This is only required to send packets earlier than
 the next call to `host:service`, or if `host:service` will not be called again.
@@ -167,31 +173,15 @@ Returns the number of bytes that were received by the given host.
 Returns the number of peers that are allocated for the given host. This
 represents the maximum number of possible connections.
 
-### `host:connected_peer_count()`
-Returns the number of connected (i.e. active) peers.
-
 ### `host:get_peer(index)`
-Returns the connected peer at the specified index (starting at 1). Please
-note that it is not guaranteed that the index stays the same for a single
-peer over time as enet pre-allocates memory in an array for all peers and
-sets their state to `connected` when a connection is established.
-
-For peers with closed connections the internal state is set to
-`disconnected`. The function `host:get_peer(i)` loops over all connections
-and returns the i-th connection that is active. If a peer with index j and
-j < i is disconnected all peers with index i and i > j have now index i -
-1.
+Returns the connected peer at the specified index (starting at 1). ENet
+stores all peers in an array of the corresponding host and re-uses unused
+peers for new connections. You can query the state of a peer using 
+[peer:state](#peerstate).
 
-### `peer:send(data [, channel, flag])`
-Queues a packet to be sent to peer. `data` is the contents of the packet, it
-must be a Lua string.
-
-`channel` is the channel to send the packet on. Defaults to `0`.
-
-`flag` is one of `"reliable"`, `"unsequenced"`, or `"unreliable"`. Reliable
-packets are guaranteed to arrive, and arrive in the order in which they are sent.
-Unsequenced packets are unreliable and have no guarantee on the order they
-arrive. Defaults to reliable.
+### `peer:connect_id()`
+Returns the field ENetPeer::connectID that is assigned for each
+connection.
 
 ### `peer:disconnect([data])`
 Requests a disconnection from the peer. The message is sent on the next
@@ -211,48 +201,78 @@ are sent.
 
 `data` is optional integer value to be associated with the disconnect.
 
-### `peer:reset()`
-Forcefully disconnects peer. The peer is not notified of the disconnection.
+### `peer:index()`
+Returns the index of the peer. All peers of an ENet host are kept in an
+array. This function finds and returns the index of the peer of its host
+structure.
 
 ### `peer:ping()`
 Send a ping request to peer, updates `round_trip_time`. This is called
 automatically at regular intervals.
 
-### `peer:throttle_configure(interval, acceleration, deceleration)`
-Changes the probability at which unreliable packets should not be dropped.
+### `peer:ping_interval(interval)`
+Specifies the interval in milliseconds that pings are sent to the other
+end of the connection (defaults to 500).
 
-Parameters:
+### `peer:reset()`
+Forcefully disconnects peer. The peer is not notified of the disconnection.
 
- * `interval` interval in milliseconds to measure lowest mean RTT
- * `acceleration` rate at which to increase throttle probability as mean RTT
-   declines
- * `deceleration` rate at which to decrease throttle probability as mean RTT
-   increases
+### `peer:send(data [, channel, flag])`
+Queues a packet to be sent to peer. `data` is the contents of the packet, it
+must be a Lua string.
+
+`channel` is the channel to send the packet on. Defaults to `0`.
+
+<a name="peersenddata__channel_flag"></a>
+`flag` is one of `"reliable"`, `"unsequenced"`, or `"unreliable"`. Reliable
+packets are guaranteed to arrive, and arrive in the order in which they are sent.
+Unsequenced packets are unreliable and have no guarantee on the order they
+arrive. Defaults to reliable.
+
+<a name="peerstate"></a>
+### `peer:state()`
+Returns the state of the peer as a string. This can be any of the
+following:
+
+ * "disconnected"
+ * "connecting"
+ * "acknowledging_connect"
+ * "connection_pending"
+ * "connection_succeeded"
+ * "connected"
+ * "disconnect_later"
+ * "disconnecting"
+ * "acknowledging_disconnect"
+ * "zombie"
+ * "unknown"
 
 ### `peer:receive()`
 Attempts to dequeue an incoming packet for this peer.
 Returns `nil` if there are no packets waiting. Otherwise returns two values:
 the string representing the packet data, and the channel the packet came from.
 
-### `peer:round_trip_time(value)`
-Returns or sets the current round trip time (i.e. ping). If value is nil
-the current value of the peer is returned. Otherwise the value roundTripTime
-is set to the specified value and returned.
-
-Enet performs some filtering on
-the round trip times and it takes some time until the parameters are
-accurate.
-
-### `peer:round_trip_time(value)`
+### `peer:round_trip_time([value])`
 Returns or sets the round trip time of the previous round trip time
 computation. If value is nil the current value of the peer is returned.
 Otherwise the value lastRoundTripTime is set to the specified value and
 returned. 
 
 Enet performs some filtering on the round trip times and it takes
-some time until the parameters are accurate.
+some time until the parameters are accurate. To speed it up you can set
+the value of the round trip time to a more accurate guess.
+
+### `peer:throttle_configure(interval, acceleration, deceleration)`
+Changes the probability at which unreliable packets should not be dropped.
+
+Parameters:
+
+ * `interval` interval in milliseconds to measure lowest mean RTT
+ * `acceleration` rate at which to increase throttle probability as mean RTT
+   declines
+ * `deceleration` rate at which to decrease throttle probability as mean RTT
+   increases
 
-### `limit, minimum, maximum peer:timeout(limit, minimum, maximum)`
+### `(limit, minimum, maximum) peer:timeout(limit, minimum, maximum)`
 Returns or sets the parameters when a timeout is detected. This is happens
 either after a fixed timeout or a variable timeout of time that takes the
 round trip time into account. The former is specified with the `maximum`

+ 112 - 37
enet.c

@@ -84,6 +84,21 @@ static void parse_address(lua_State *l, const char *addr_str, ENetAddress *addre
 	}
 }
 
+/**
+ * Find the index of a given peer for which we only have the pointer.
+ */
+size_t find_peer_index (lua_State *l, ENetHost *enet_host, ENetPeer *peer) {
+	size_t peer_index;
+	for (peer_index = 0; peer_index < enet_host->peerCount; peer_index++) {
+		if (peer == &(enet_host->peers[peer_index]))
+			return peer_index;
+	}
+
+	luaL_error (l, "enet: could not find peer id!");
+
+	return peer_index;
+}
+
 static void push_peer(lua_State *l, ENetPeer *peer) {
 	// try to find in peer table
 	lua_getfield(l, LUA_REGISTRYINDEX, "enet_peers");
@@ -187,6 +202,10 @@ static ENetPacket *read_packet(lua_State *l, int idx, enet_uint8 *channel_id) {
  * Create a new host
  * Args:
  * 	address (nil for client)
+ * 	[peer_count = 64]
+ * 	[channel_count = 1]
+ * 	[in_bandwidth = 0]
+ * 	[out_bandwidth = 0]
  */
 static int host_create(lua_State *l) {
 	ENetHost *host;
@@ -270,10 +289,29 @@ static int host_check_events(lua_State *l) {
 	return 1;
 }
 
+/**
+ * Enables an adaptive order-2 PPM range coder for the transmitted data of
+ * all peers.
+ */
+static int host_compress_with_range_coder(lua_State *l) {
+	ENetHost *host = check_host(l, 1);
+
+	int result = enet_host_compress_with_range_coder (host);
+	if (result == 0) {
+		lua_pushboolean (l, 1);
+	} else {
+		lua_pushboolean (l, 0);
+	}
+
+	return 1;
+}
+
 /**
  * Connect a host to an address
  * Args:
  * 	the address
+ * 	[channel_count = 1]
+ * 	[data = 0]
  */
 static int host_connect(lua_State *l) {
 	ENetHost *host = check_host(l, 1);
@@ -366,43 +404,16 @@ static int host_peer_count(lua_State *l) {
 	return 1;
 }
 
-static int host_connected_peer_count(lua_State *l) {
-	ENetHost *host = check_host(l, 1);
-	unsigned int connected_peer_count = 0;
-
-	ENetPeer *peer;
-	for (peer = host->peers; peer < &host->peers[host->peerCount]; ++peer) {
-		if (peer->state != ENET_PEER_STATE_CONNECTED 
-				&& peer->state != ENET_PEER_STATE_DISCONNECT_LATER)
-			continue;
-
-		connected_peer_count++;
-	}
-
-	lua_pushinteger (l, connected_peer_count);
-
-	return 1;
-}
-
 static int host_get_peer(lua_State *l) {
 	ENetHost *host = check_host(l, 1);
 
-	unsigned int peer_index = luaL_checkint(l, 2) - 1;
-	ENetPeer *peer;
-
-	for (peer = host->peers; peer < &host->peers[host->peerCount]; ++peer) {
-		if (peer->state != ENET_PEER_STATE_CONNECTED 
-				&& peer->state != ENET_PEER_STATE_DISCONNECT_LATER)
-			continue;
+	int peer_index = luaL_checkint(l, 2) - 1;
 
-		if (peer_index == 0)
-			break;
-
-		peer_index --;
+	if (peer_index < 0 || peer_index >= host->peerCount) {
+		luaL_argerror (l, 2, "Invalid peer index");
 	}
 
-	if (peer_index > 0)
-		return 0;
+	ENetPeer *peer = &(host->peers[peer_index]);
 
 	push_peer (l, peer);
 	return 1;
@@ -530,6 +541,65 @@ static int peer_disconnect_later(lua_State *l) {
 	return 0;
 }
 
+static int peer_index(lua_State *l) {
+	ENetPeer *peer = check_peer(l, 1);
+
+	size_t peer_index = find_peer_index (l, peer->host, peer);
+	lua_pushinteger (l, peer_index + 1);
+
+	return 1;
+}
+
+static int peer_state(lua_State *l) {
+	ENetPeer *peer = check_peer(l, 1);
+
+	switch (peer->state) {
+		case (ENET_PEER_STATE_DISCONNECTED):
+			lua_pushstring (l, "disconnected");
+			break;
+		case (ENET_PEER_STATE_CONNECTING):
+			lua_pushstring (l, "connecting");
+			break;
+		case (ENET_PEER_STATE_ACKNOWLEDGING_CONNECT):
+			lua_pushstring (l, "acknowledging_connect");
+			break;
+		case (ENET_PEER_STATE_CONNECTION_PENDING):
+			lua_pushstring (l, "connection_pending");
+			break;
+		case (ENET_PEER_STATE_CONNECTION_SUCCEEDED):
+			lua_pushstring (l, "connection_succeeded");
+			break;
+		case (ENET_PEER_STATE_CONNECTED):
+			lua_pushstring (l, "connected");
+			break;
+		case (ENET_PEER_STATE_DISCONNECT_LATER):
+			lua_pushstring (l, "disconnect_later");
+			break;
+		case (ENET_PEER_STATE_DISCONNECTING):
+			lua_pushstring (l, "disconnecting");
+			break;
+		case (ENET_PEER_STATE_ACKNOWLEDGING_DISCONNECT):
+			lua_pushstring (l, "acknowledging_disconnect");
+			break;
+		case (ENET_PEER_STATE_ZOMBIE):
+			lua_pushstring (l, "zombie");
+			break;
+		default:
+			lua_pushstring (l, "unknown");
+	}
+
+	return 1;
+}
+
+static int peer_connect_id(lua_State *l) {
+	ENetPeer *peer = check_peer(l, 1);
+
+	lua_pushinteger (l, peer->connectID);
+
+	return 1;
+}
+
+
 static int peer_reset(lua_State *l) {
 	ENetPeer *peer = check_peer(l, 1);
 	enet_peer_reset(peer);
@@ -583,16 +653,18 @@ static const struct luaL_Reg enet_funcs [] = {
 static const struct luaL_Reg enet_host_funcs [] = {
 	{"service", host_service},
 	{"check_events", host_check_events},
+	{"compress_with_range_coder", host_compress_with_range_coder},
 	{"connect", host_connect},
-	{"broadcast", host_broadcast},
 	{"flush", host_flush},
+	{"broadcast", host_broadcast},
 	{"channel_limit", host_channel_limit},
 	{"bandwidth_limit", host_bandwidth_limit},
+
+	// additional convenience functions (mostly accessors)
 	{"total_sent_data", host_total_sent_data},
 	{"total_received_data", host_total_received_data},
 	{"service_time", host_service_time},
 	{"peer_count", host_peer_count},
-	{"connected_peer_count", host_connected_peer_count},
 	{"get_peer", host_get_peer},
 	{NULL, NULL}
 };
@@ -606,10 +678,15 @@ static const struct luaL_Reg enet_peer_funcs [] = {
 	{"receive", peer_receive},
 	{"send", peer_send},
 	{"throttle_configure", peer_throttle_configure},
-	{"round_trip_time", peer_round_trip_time},
-	{"last_round_trip_time", peer_last_round_trip_time},
 	{"ping_interval", peer_ping_interval},
 	{"timeout", peer_timeout},
+
+	// additional convenience functions to member variables
+	{"index", peer_index},
+	{"state", peer_state},
+	{"connect_id", peer_connect_id},
+	{"round_trip_time", peer_round_trip_time},
+	{"last_round_trip_time", peer_last_round_trip_time},
 	{NULL, NULL}
 };
 
@@ -636,7 +713,6 @@ LUALIB_API int luaopen_enet(lua_State *l) {
 	lua_pushcfunction(l, peer_tostring);
 	lua_setfield(l, -2, "__tostring");
 
-
 	// set up peer table
 	lua_newtable(l);
 
@@ -650,4 +726,3 @@ LUALIB_API int luaopen_enet(lua_State *l) {
 	luaL_register(l, "enet", enet_funcs);
 	return 0;
 }
-