First working version with disconnection
This commit is contained in:
parent
2a8e3ea323
commit
bf0fa516d4
@ -47,6 +47,10 @@ export class Group {
|
|||||||
return this.users.length >= Group.MAX_PER_GROUP;
|
return this.users.length >= Group.MAX_PER_GROUP;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
isEmpty(): boolean {
|
||||||
|
return this.users.length <= 1;
|
||||||
|
}
|
||||||
|
|
||||||
join(user: UserInterface): void
|
join(user: UserInterface): void
|
||||||
{
|
{
|
||||||
// Broadcast on the right event
|
// Broadcast on the right event
|
||||||
@ -79,7 +83,7 @@ export class Group {
|
|||||||
return stillIn;
|
return stillIn;
|
||||||
}
|
}
|
||||||
|
|
||||||
removeFromGroup(users: UserInterface[]): void
|
/*removeFromGroup(users: UserInterface[]): void
|
||||||
{
|
{
|
||||||
for(let i = 0; i < users.length; i++){
|
for(let i = 0; i < users.length; i++){
|
||||||
let user = users[i];
|
let user = users[i];
|
||||||
@ -88,5 +92,32 @@ export class Group {
|
|||||||
this.users.splice(index, 1);
|
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);
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -29,6 +29,8 @@ export class World {
|
|||||||
id: userPosition.userId,
|
id: userPosition.userId,
|
||||||
position: userPosition.position
|
position: userPosition.position
|
||||||
});
|
});
|
||||||
|
// Let's call update position to trigger the join / leave room
|
||||||
|
this.updatePosition(userPosition);
|
||||||
}
|
}
|
||||||
|
|
||||||
public leave(user : ExSocketInterface){
|
public leave(user : ExSocketInterface){
|
||||||
@ -60,18 +62,39 @@ export class World {
|
|||||||
user,
|
user,
|
||||||
closestUser
|
closestUser
|
||||||
], this.connectCallback, this.disconnectCallback);
|
], this.connectCallback, this.disconnectCallback);
|
||||||
|
this.groups.push(group);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// If the user is part of a group:
|
// 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<MIN_DISTANCE"
|
* Makes a user leave a group and closes and destroy the group if the group contains only one remaining person.
|
||||||
// If some users are not in the subgroup, take the other user and loop
|
*
|
||||||
// At the end, we will have a list of subgroups. From this list, we can send disconnect messages
|
* @param user
|
||||||
|
*/
|
||||||
|
private leaveGroup(user: UserInterface): void {
|
||||||
|
let group = user.group;
|
||||||
|
if (typeof group === 'undefined') {
|
||||||
|
throw new Error("The user is part of no group");
|
||||||
|
}
|
||||||
|
group.leave(user);
|
||||||
|
|
||||||
|
if (group.isEmpty()) {
|
||||||
|
group.destroy();
|
||||||
|
const index = this.groups.indexOf(group, 0);
|
||||||
|
if (index === -1) {
|
||||||
|
throw new Error("Could not find group");
|
||||||
|
}
|
||||||
|
this.groups.splice(index, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -141,7 +164,6 @@ export class World {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let distance = World.computeDistanceBetweenPositions(user.position, group.getPosition());
|
let distance = World.computeDistanceBetweenPositions(user.position, group.getPosition());
|
||||||
|
|
||||||
if(distance <= minimumDistanceFound) {
|
if(distance <= minimumDistanceFound) {
|
||||||
minimumDistanceFound = distance;
|
minimumDistanceFound = distance;
|
||||||
matchingItem = group;
|
matchingItem = group;
|
||||||
|
@ -54,6 +54,50 @@ describe("World", () => {
|
|||||||
expect(connectCalled).toBe(false);
|
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", () => {
|
it("should disconnect user1 and user2", () => {
|
||||||
let connectCalled: boolean = false;
|
let connectCalled: boolean = false;
|
||||||
let disconnectCalled: boolean = false;
|
let disconnectCalled: boolean = false;
|
||||||
@ -78,12 +122,13 @@ describe("World", () => {
|
|||||||
position: new Point(259, 100)
|
position: new Point(259, 100)
|
||||||
}));
|
}));
|
||||||
|
|
||||||
expect(connectCalled).toBe(false);
|
expect(connectCalled).toBe(true);
|
||||||
|
expect(disconnectCalled).toBe(false);
|
||||||
|
|
||||||
world.updatePosition(new MessageUserPosition({
|
world.updatePosition(new MessageUserPosition({
|
||||||
userId: "bar",
|
userId: "bar",
|
||||||
roomId: 1,
|
roomId: 1,
|
||||||
position: new Point(261, 100)
|
position: new Point(100+160+160+1, 100)
|
||||||
}));
|
}));
|
||||||
|
|
||||||
expect(disconnectCalled).toBe(true);
|
expect(disconnectCalled).toBe(true);
|
||||||
|
Loading…
Reference in New Issue
Block a user