/* * Copyright (c) 2005-2010 KOM – Multimedia Communications Lab * * This file is part of PeerfactSim.KOM. * * PeerfactSim.KOM 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 3 of the License, or * any later version. * * PeerfactSim.KOM 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 PeerfactSim.KOM. If not, see . * */ package de.tud.kom.p2psim.impl.topology.movement.modularosm.groups; import java.util.LinkedHashSet; import java.util.Random; import java.util.UUID; import de.tud.kom.p2psim.api.topology.movement.SimLocationActuator; import de.tud.kom.p2psim.impl.topology.util.PositionVector; import de.tudarmstadt.maki.simonstrator.api.Randoms; /** * This class handles the instance of a group. Each group instance has a leader which sets the behavior. All other * participants follow the behavior of the leader in terms of speed, velocity, heading etc. * * @author Julian Zobel */ public class SocialMovementGroup { public final UUID groupID; private Random rand = Randoms.getRandom(SocialMovementGroup.class); private SimLocationActuator leader; private LinkedHashSet members; private PositionVector destination; private PositionVector meetingPoint; /** * Initializes the group with a given leader. * * @param SimLocationActuator New leader of the group * @param int The ID of the group. */ public SocialMovementGroup(SimLocationActuator leader) { this.groupID = UUID.randomUUID(); this.leader = leader; this.members = new LinkedHashSet(); this.members.add(leader); } /** * Initializes the group, sets the participants and groupId, finally chooses a random leader. * * @param Set All participants of the group. * @param int The ID of the group. */ public SocialMovementGroup(LinkedHashSet participants) { this.groupID = UUID.randomUUID(); setMembers(participants); setRandomLeader(); } /** * Adds a host to the group. Manually check in {@link ModularMovementModel} class, if group size is exceeded by adding another host. * * @param SimLocationActuator The host to be added. */ public void addHostToGroup(SimLocationActuator host) { members.add(host); } /** * Removes a host from the group. If the host was the current leader, a random new leader is chosen from the remaining members. * * @param SimLocationActuator The host to be removed. */ public void removeHostFromGroup(SimLocationActuator host) { if(members.contains(host)) { if(host == leader) { members.remove(host); setRandomLeader(); } else { members.remove(host); } } } /** * Sets a randomly chosen participant of the group as leader. */ private void setRandomLeader() { this.leader = getRandomMember(); } /** * Returns a random participant of all group members. * * @return SimLocationActuator */ public SimLocationActuator getRandomMember() { if(members.size() > 1) { int item = rand.nextInt(members.size() - 1); int i = 0; for(SimLocationActuator host : members) { if(i == item) { return host; } i++; } } else if(members.size() == 1) { return members.iterator().next(); } return null; } /** * Returns true if this group has a specific host as member, false otherwise * * @param SimLocationActuator The host to be checked. * @return boolean */ public boolean hasMember(SimLocationActuator host) { if(members.contains(host)) { return true; } return false; } /** * Returns the position of the group leader. * * @return PositionVector The position of the group leader. */ public PositionVector getLeaderPosition() { return leader.getRealPosition(); } @Override public String toString() { return "Social Group of Leader #" + leader.getHost().getId() + " ("+ members.size() +")"; } // =================== // Getters and Setters // =================== public int getGroupSize() { return members.size(); } public LinkedHashSet getMembers() { return new LinkedHashSet(members); } public void setMembers(LinkedHashSet participants) { this.members = new LinkedHashSet<>(participants); } public SimLocationActuator getLeader() { return leader; } public PositionVector getDestination() { return destination; } public void setDestination(PositionVector destination) { this.destination = destination; } public PositionVector getMeetingPoint() { return meetingPoint; } public void setMeetingPoint(PositionVector meetingPoint) { this.meetingPoint = meetingPoint; } @Override public boolean equals(Object obj) { if(!(obj instanceof SocialMovementGroup)) { return false; } SocialMovementGroup toCompare = (SocialMovementGroup) obj; if(this.groupID == toCompare.groupID) { if(this.getLeader() == toCompare.getLeader()) { return true; } else { System.out.println("Leader seems to be different, but still the same UUID"); return false; } } else return false; } @Override public int hashCode() { //FIXME hope this is correct -- should we include the leader and/or other fields as well? return groupID.hashCode(); } }