Skip to content

Commit

Permalink
start pubsub feature branch w/ tanks example
Browse files Browse the repository at this point in the history
  • Loading branch information
jbakse committed Jan 12, 2022
1 parent 2e530ca commit c97afca
Show file tree
Hide file tree
Showing 6 changed files with 222 additions and 0 deletions.
8 changes: 8 additions & 0 deletions public/examples/tanks/README.md
@@ -0,0 +1,8 @@
# drag

Create and arrange items on a shared chart.

- **click create** to craete a new card
- **drag** to move an item

> Open this example in two browser windows at once!
29 changes: 29 additions & 0 deletions public/examples/tanks/index.html
@@ -0,0 +1,29 @@
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="../sketch.css" />
<style>
body {
display: flex;
}
#create {
padding: 10px;
}
#shared {
background: #eee;
white-space: pre;
}
</style>
</head>
<body>
<div id="canvas-wrap"></div>
<div id="shared"></div>
<script src="https://unpkg.com/uuid@latest/dist/umd/uuidv4.min.js"></script>

<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.0.0/p5.min.js"></script>

<script src="/dist/p5.party.js"></script>

<script src="index.js"></script>
</body>
</html>
139 changes: 139 additions & 0 deletions public/examples/tanks/index.js
@@ -0,0 +1,139 @@
/* global uuidv4 */
/* global partyEmit partySubscribe*/

class Rect {
constructor(l = 0, t = 0, w = 0, h = 0) {
this.l = l;
this.t = t;
this.w = w;
this.h = h;
}
}

class Point {
constructor(x = 0, y = 0) {
this.x = x;
this.y = y;
}
}

function pointInRect(p, r) {
return p.x > r.l && p.x < r.l + r.w && p.y > r.t && p.y < r.t + r.h;
}

const bounds = new Rect(0, 0, 400, 400);

let shared, send, me, participants;

function preload() {
partyConnect("wss://deepstream-server-1.herokuapp.com", "tanks", "main");
shared = partyLoadShared("shared");
send = partyLoadShared("send");
me = partyLoadMyShared();
participants = partyLoadParticipantShareds();
}

function setup() {
createCanvas(400, 400).parent("canvas-wrap");

noStroke();

if (partyIsHost()) {
shared.bullets = [];
send.bullets = [];
}
me.tank = { x: 100, y: 100, a: 0 };

partySubscribe("createBullet", (d) => {
if (partyIsHost()) {
console.log("partySubscribe", d);
}
});
}

function draw() {
checkKeys();
showData();
if (partyIsHost()) stepGame();
drawScene();
}

function stepGame() {
// copy sent bullets to main bullet array
while (send.bullets.length) {
shared.bullets.push(send.bullets.shift());
}

// step bullets
shared.bullets.forEach(stepBullet);
}

function showData() {
document.getElementById("shared").innerText = JSON.stringify(
shared,
null,
"\t"
);
}
function drawScene() {
background("#cc6666");
shared.bullets.forEach(drawBullet);
for (const p of participants) {
if (p.tank) drawTank(p.tank);
}
}

function drawTank(tank) {
push();
rectMode(CENTER);
translate(tank.x, tank.y);
rotate(tank.a);
rect(0, 0, 30, 30);
rect(0, -20, 5, 5);
pop();
}

function stepBullet(b) {
b.x += b.dX;
b.y += b.dY;
if (!pointInRect(b, bounds)) {
const i = shared.bullets.indexOf(b);
shared.bullets.splice(i, 1);
}
}

function drawBullet(b) {
push();
ellipse(b.x, b.y, 10, 10);
pop();
}

function keyPressed() {
if (key === " ") {
// send.bullets.push({
// x: me.tank.x,
// y: me.tank.y,
// dX: sin(me.tank.a) * 6,
// dY: -cos(me.tank.a) * 6,
// });
partyEmit("createBullet", "hell yeah");
}

return false;
}
function checkKeys() {
// forward
if (keyIsDown(87) /*w*/) {
me.tank.x += sin(me.tank.a) * 3;
me.tank.y -= cos(me.tank.a) * 3;
}

// backward
if (keyIsDown(83) /*s*/) {
me.tank.x += sin(me.tank.a) * -1;
me.tank.y -= cos(me.tank.a) * -1;
}

if (keyIsDown(65) /*a*/) me.tank.a -= radians(2);
if (keyIsDown(68) /*d*/) me.tank.a += radians(2);
}
26 changes: 26 additions & 0 deletions public/examples/tanks/notes.md
@@ -0,0 +1,26 @@
when two players try to alter the same share object at the same time, one or the other share object "wins"

even if the changes are to different properties of the shared object, one change is lost

this commonly happens when the host is trying to animate some data in a shared object (like moving a bullet) and another player tires to change _anything_ in the same shared object

i just tried working around this by having players add bullets in their own shared object and the host moves them over into the main shared.

this way the players don't write to shared at all

it partly worked but...

now the player writes new bullets to its own participant share + the host removes bullets from that share so they are both writing to the same share. If the player is writing to it a lot (like the player is turning when the shot is fired) we end up with the same kind of problem.

possible solution:
create a second global shared
all particpants write new bullets there
host consumes them
now we have multiple players + hosts writing to the same record, but not rapidly.

This is starting to look a lot like a message sending or event scheme. And deepstream does have Event stuff built in, and maybe that should be exposed by p5.party?

https://deepstream.io/tutorials/core/pubsub/

con - more complixty to the API
pro - maybe less complexity/workarounds in sketch code
10 changes: 10 additions & 0 deletions src/Client.js
Expand Up @@ -84,4 +84,14 @@ export class Client {
name() {
return this.#name;
}

////////////////////////////////////////////////
// experimental pub/sub
subscribe(event, cb) {
this.#deepstreamClient.event.subscribe(event, cb);
}

emit(event, data) {
this.#deepstreamClient.event.emit(event, data);
}
}
10 changes: 10 additions & 0 deletions src/index_p5.js
Expand Up @@ -148,4 +148,14 @@ function init() {
}
Record.recordForShared(shared).watchShared(path, cb);
};

////////////////////////////////////////////////
// experimental pub/sub
p5.prototype.partySubscribe = function (event, cb) {
__client.subscribe(event, cb);
};

p5.prototype.partyEmit = function (event, data) {
__client.emit(event, data);
};
}

0 comments on commit c97afca

Please sign in to comment.