Skip to content

Commit

Permalink
Merge 10b9ea7 into 6c2331b
Browse files Browse the repository at this point in the history
  • Loading branch information
delucis committed Sep 4, 2021
2 parents 6c2331b + 10b9ea7 commit 06ab80a
Show file tree
Hide file tree
Showing 16 changed files with 597 additions and 47 deletions.
1 change: 1 addition & 0 deletions examples/react-web/src/index.html
@@ -1,6 +1,7 @@
<!DOCTYPE html>
<html>
<head>
<meta content="width=device-width,initial-scale=1" name="viewport">
<link rel="stylesheet" href="//unpkg.com/docsify/lib/themes/vue.css">
</head>
<body class="ready sticky">
Expand Down
89 changes: 89 additions & 0 deletions examples/react-web/src/p2p/configurator.js
@@ -0,0 +1,89 @@
import React from 'react';

export const Configurator = ({
isHost,
setIsHost,
playerID,
setPlayerID,
matchID,
setMatchID,
onSubmit,
}) => (
<>
<h2>Configure this client</h2>
<form
style={{
display: 'grid',
gap: '2rem',
maxWidth: '30rem',
}}
onSubmit={(e) => {
e.preventDefault();
onSubmit();
}}
>
<label>
<code>isHost</code>{' '}
<input
type="checkbox"
checked={isHost}
onChange={(e) => setIsHost(e.currentTarget.checked)}
/>
</label>
<label>
<code>playerID</code>{' '}
<select
value={playerID}
onChange={(e) => setPlayerID(e.currentTarget.value)}
>
<option value={''}>spectator</option>
<option value="0">0</option>
<option value="1">1</option>
</select>
</label>
<label>
<code>matchID</code>{' '}
<input
type="text"
value={matchID}
onInput={(e) => setMatchID(e.currentTarget.value)}
/>
</label>
<button type="submit">Connect</button>
</form>
<Instructions />
</>
);

function Instructions() {
return (
<small style={{ display: 'block', marginTop: '4rem' }}>
<h2>Instructions</h2>
<h3>Window/Computer 1</h3>
<ol>
<li>
Click <code>isHost</code> and select your choice of{' '}
<code>playerID</code>.
</li>
<li>
Copy the <code>matchID</code>.
</li>
<li>
Click <strong>Connect</strong>.
</li>
</ol>
<h3>Window/Computer 2</h3>
<ol>
<li>
Select the other <code>playerID</code>.
</li>
<li>
Paste/type the <code>matchID</code> from the other window.
</li>
<li>
Click <strong>Connect</strong>.
</li>
</ol>
</small>
);
}
19 changes: 19 additions & 0 deletions examples/react-web/src/p2p/index.js
@@ -0,0 +1,19 @@
/*
* Copyright 2021 The boardgame.io Authors.
*
* Use of this source code is governed by a MIT-style
* license that can be found in the LICENSE file or at
* https://opensource.org/licenses/MIT.
*/

import P2P from './p2p';

const routes = [
{
path: '/p2p/tic-tac-toe',
text: 'Tic-Tac-Toe',
component: P2P,
},
];

export default { routes };
80 changes: 80 additions & 0 deletions examples/react-web/src/p2p/p2p.js
@@ -0,0 +1,80 @@
/*
* Copyright 2021 The boardgame.io Authors
*
* Use of this source code is governed by a MIT-style
* license that can be found in the LICENSE file or at
* https://opensource.org/licenses/MIT.
*/

import React, { useState, useEffect } from 'react';
import { Client } from 'boardgame.io/react';
import { P2P } from 'boardgame.io/multiplayer';
import { nanoid } from 'nanoid';
import TicTacToe from '../tic-tac-toe/game';
import Board from '../tic-tac-toe/board';
import { Configurator } from './configurator';

const View = () => {
const [matchID, setMatchID] = useState(() => nanoid());
const [playerID, setPlayerID] = useState('0');
const [isHost, setIsHost] = useState(false);
const [showClient, setShowClient] = useState(false);
const [GameView, setGameView] = useState(null);
const onSubmit = () => setShowClient(true);

useEffect(() => {
if (showClient) {
setGameView(() =>
Client({
game: TicTacToe,
board: Board,
multiplayer: P2P({ isHost }),
})
);
} else {
setGameView(null);
}
}, [showClient, isHost]);

if (!GameView) {
return (
<Configurator
{...{
matchID,
setMatchID,
playerID,
setPlayerID,
isHost,
setIsHost,
onSubmit,
}}
/>
);
}

return (
<div>
<GameView {...{ playerID, matchID }} />
<p>
<code>
&lt;Client matchID="{matchID}" playerID="{playerID}" /&gt;
</code>
</p>
{isHost && <p>This is the match host.</p>}
<p>
<button onClick={() => setShowClient(false)}>Back</button>
</p>
</div>
);
};

const App = () => {
return (
<div>
<h1>Peer-to-Peer</h1>
<View />
</div>
);
};

export default App;
5 changes: 5 additions & 0 deletions examples/react-web/src/routes.js
Expand Up @@ -8,6 +8,7 @@

import tic_tac_toe from './tic-tac-toe';
import chess from './chess';
import p2p from './p2p';
import secret_state from './secret-state';
import random from './random';
import threejs from './threejs';
Expand All @@ -25,6 +26,10 @@ const routes = [
name: 'Chess',
routes: chess.routes,
},
{
name: 'Peer-to-Peer Multiplayer',
routes: p2p.routes,
},
{
name: 'Turn Orders',
routes: simulator.routes,
Expand Down
50 changes: 50 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Expand Up @@ -157,6 +157,7 @@
"lodash.isplainobject": "^4.0.6",
"nanoid": "^3.1.23",
"p-queue": "^6.6.2",
"peerjs": "^1.3.2",
"prop-types": "^15.5.10",
"react-cookies": "^0.1.0",
"redux": "^4.1.0",
Expand Down
3 changes: 2 additions & 1 deletion packages/multiplayer.ts
Expand Up @@ -8,5 +8,6 @@

import { Local } from '../src/client/transport/local';
import { SocketIO } from '../src/client/transport/socketio';
import { P2P } from '../src/client/transport/p2p';

export { Local, SocketIO };
export { Local, SocketIO, P2P };
2 changes: 1 addition & 1 deletion src/client/client.test.ts
Expand Up @@ -771,7 +771,7 @@ describe('subscribe', () => {
client.subscribe(fn);
client.start();
fn.mockClear();
transport.callback();
(transport as any).callback();
expect(fn).toHaveBeenCalled();
client.stop();
});
Expand Down
2 changes: 1 addition & 1 deletion src/client/transport/local.test.ts
Expand Up @@ -227,7 +227,7 @@ describe('LocalMaster', () => {
test('connect', () => {
localA.connect();
localB.connect();
localA.subscribe();
localA.subscribe(jest.fn());

expect(storeA.dispatch).toBeCalledWith(
expect.objectContaining({
Expand Down
14 changes: 1 addition & 13 deletions src/client/transport/local.ts
Expand Up @@ -12,7 +12,7 @@ import { LocalStorage } from '../../server/db/localstorage';
import { Master } from '../../master/master';
import type { TransportAPI, TransportData } from '../../master/master';
import { Transport } from './transport';
import type { TransportOpts, ChatCallback } from './transport';
import type { TransportOpts } from './transport';
import type {
ChatMessage,
CredentialedActionShape,
Expand Down Expand Up @@ -140,7 +140,6 @@ type LocalTransportOpts = TransportOpts & {
*/
export class LocalTransport extends Transport {
master: LocalMaster;
chatMessageCallback: ChatCallback;

/**
* Creates a new Mutiplayer instance.
Expand Down Expand Up @@ -229,17 +228,6 @@ export class LocalTransport extends Transport {
*/
disconnect() {}

/**
* Subscribe to connection state changes.
*/
subscribe() {}

subscribeMatchData() {}

subscribeChatMessage(fn: ChatCallback) {
this.chatMessageCallback = fn;
}

/**
* Dispatches a reset action, then requests a fresh sync from the master.
*/
Expand Down

0 comments on commit 06ab80a

Please sign in to comment.