summaryrefslogtreecommitdiff
path: root/src/uqm/supermelee/netplay/proto/ready.c
blob: e9f8c58d2d972ec2a2c955a921a2eb7eb5b49721 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
/*
 *  Copyright 2006  Serge van den Boom <svdb@stack.nl>
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#define NETCONNECTION_INTERNAL
#include "../netplay.h"
#include "ready.h"

#include "types.h"
#include "../netmisc.h"
#include "../packetsenders.h"

#include <assert.h>

static void
Netplay_bothReady(NetConnection *conn) {
	NetConnection_ReadyCallback callback;
	void *readyArg;

	assert(conn->readyCallback != NULL);

	callback = conn->readyCallback;
	readyArg = conn->readyCallbackArg;

	NetConnection_setReadyCallback(conn, NULL, NULL);
			// Clear the readyCallback field before performing the callback,
			// so that it can be set again from inside the callback
			// function.

	callback(conn, readyArg);
}

// If notifyRemote is set, a 'Ready' message will be sent to the other side.
// returns true iff both sides are ready.
// Inside the callback function, ready flags may be set for a possible
// next Ready communication.
bool
Netplay_localReady(NetConnection *conn, NetConnection_ReadyCallback callback,
		void *readyArg, bool notifyRemote) {
	assert(readyFlagsMeaningful(NetConnection_getState(conn)));
	assert(!conn->stateFlags.ready.localReady);
	assert(callback != NULL);

	NetConnection_setReadyCallback(conn, callback, readyArg);

	if (notifyRemote)
		sendReady(conn);
	if (!conn->stateFlags.ready.remoteReady) {
		conn->stateFlags.ready.localReady = true;
		return false;
	}

	// Reset ready flags:
	conn->stateFlags.ready.remoteReady = false;

	// Trigger the callback.
	Netplay_bothReady(conn);
	return true;
}

// returns true iff both sides are ready.
bool
Netplay_remoteReady(NetConnection *conn) {
	assert(readyFlagsMeaningful(NetConnection_getState(conn)));
			// This is supposed to be already verified by the calling
			// function.
	assert(!conn->stateFlags.ready.remoteReady);
	
	if (!conn->stateFlags.ready.localReady) {
		conn->stateFlags.ready.remoteReady = true;
		return false;
	}

	// Reset ready flags:
	conn->stateFlags.ready.localReady = false;

	// Trigger the callback.
	Netplay_bothReady(conn);
	return true;
}

bool
Netplay_isLocalReady(const NetConnection *conn) {
	return conn->stateFlags.ready.localReady;
}

bool
Netplay_isRemoteReady(const NetConnection *conn) {
	return conn->stateFlags.ready.remoteReady;
}