From bf0fa516d49486a68b7e747bda839c254bec60ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20N=C3=A9grier?= Date: Wed, 29 Apr 2020 23:12:55 +0200 Subject: [PATCH] First working version with disconnection --- back/src/Model/Group.ts | 33 ++++++++++++++++++++++++++- back/src/Model/World.ts | 34 +++++++++++++++++++++++----- back/tests/WorldTest.ts | 49 +++++++++++++++++++++++++++++++++++++++-- 3 files changed, 107 insertions(+), 9 deletions(-) diff --git a/back/src/Model/Group.ts b/back/src/Model/Group.ts index 9f5c48c5..caf9b926 100644 --- a/back/src/Model/Group.ts +++ b/back/src/Model/Group.ts @@ -47,6 +47,10 @@ export class Group { return this.users.length >= Group.MAX_PER_GROUP; } + isEmpty(): boolean { + return this.users.length <= 1; + } + join(user: UserInterface): void { // Broadcast on the right event @@ -79,7 +83,7 @@ export class Group { return stillIn; } - removeFromGroup(users: UserInterface[]): void + /*removeFromGroup(users: UserInterface[]): void { for(let i = 0; i < users.length; i++){ let user = users[i]; @@ -88,5 +92,32 @@ export class Group { this.users.splice(index, 1); } } + }*/ + + leave(user: UserInterface): void + { + const index = this.users.indexOf(user, 0); + if (index === -1) { + throw new Error("Could not find user in the group"); + } + + this.users.splice(index, 1); + user.group = undefined; + + // Broadcast on the right event + this.users.forEach((groupUser: UserInterface) => { + this.disconnectCallback(user.id, groupUser.id); + }); + } + + /** + * Let's kick everybody out. + * Usually used when there is only one user left. + */ + destroy(): void + { + this.users.forEach((user: UserInterface) => { + this.leave(user); + }) } } diff --git a/back/src/Model/World.ts b/back/src/Model/World.ts index 32e1b383..06bcf884 100644 --- a/back/src/Model/World.ts +++ b/back/src/Model/World.ts @@ -29,6 +29,8 @@ export class World { id: userPosition.userId, position: userPosition.position }); + // Let's call update position to trigger the join / leave room + this.updatePosition(userPosition); } public leave(user : ExSocketInterface){ @@ -60,18 +62,39 @@ export class World { user, closestUser ], this.connectCallback, this.disconnectCallback); + this.groups.push(group); } } } else { // If the user is part of a group: - // should we split the group? + // should he leave the group? + let distance = World.computeDistanceBetweenPositions(user.position, user.group.getPosition()); + if (distance > World.MIN_DISTANCE) { + this.leaveGroup(user); + } + } + } - // TODO: analyze the group of the user: - // => take one user. "walk the tree of users, each branch being a link { expect(connectCalled).toBe(false); }); + it("should connect 3 users", () => { + let connectCalled: boolean = false; + let connect = (user1: string, user2: string): void => { + connectCalled = true; + } + let disconnect = (user1: string, user2: string): void => { + + } + + let world = new World(connect, disconnect); + + world.join(new MessageUserPosition({ + userId: "foo", + roomId: 1, + position: new Point(100, 100) + })); + + world.join(new MessageUserPosition({ + userId: "bar", + roomId: 1, + position: new Point(200, 100) + })); + + expect(connectCalled).toBe(true); + connectCalled = false; + + // baz joins at the outer limit of the group + world.join(new MessageUserPosition({ + userId: "baz", + roomId: 1, + position: new Point(311, 100) + })); + + expect(connectCalled).toBe(false); + + world.updatePosition(new MessageUserPosition({ + userId: "baz", + roomId: 1, + position: new Point(309, 100) + })); + + expect(connectCalled).toBe(true); + }); + it("should disconnect user1 and user2", () => { let connectCalled: boolean = false; let disconnectCalled: boolean = false; @@ -78,12 +122,13 @@ describe("World", () => { position: new Point(259, 100) })); - expect(connectCalled).toBe(false); + expect(connectCalled).toBe(true); + expect(disconnectCalled).toBe(false); world.updatePosition(new MessageUserPosition({ userId: "bar", roomId: 1, - position: new Point(261, 100) + position: new Point(100+160+160+1, 100) })); expect(disconnectCalled).toBe(true);