Let the rating repository accept integers rather than Names, and tweak the delegate accordingly. Hrm, does this handle guests correctly, actually?

git-svn-id: svn+ssh://src.earth.threerings.net/vilya/trunk@348 c613c5cb-e716-0410-b11b-feb51c14d237
This commit is contained in:
Par Winzell
2007-07-05 23:18:44 +00:00
parent a78c1a35d9
commit 3484e8cd1f
2 changed files with 46 additions and 51 deletions
@@ -98,9 +98,9 @@ public abstract class RatingManagerDelegate
int gameId = _gmgr.getGameConfig().getGameId();
// enumerate our players
Name[] players = new Name[_gmgr.getPlayerCount()];
Integer[] players = new Integer[_gmgr.getPlayerCount()];
for (int ii = 0; ii < players.length; ii ++) {
players[ii] = _gmgr.getPlayerName(ii);
players[ii] = _gmgr.getPlayerPersistentId(_gmgr.getPlayer(ii));
}
try {
@@ -116,7 +116,7 @@ public abstract class RatingManagerDelegate
// now build the array we keep around until the end of the game
_ratings = new Rating[_gmgr.getPlayerCount()];
for (int ii = 0; ii < _ratings.length; ii ++) {
RatingRecord record = map.get(_repo.mapNameToId(_gmgr.getPlayerName(ii)));
RatingRecord record = map.get(players[ii]);
// if the player had no previous record, initiate them at default values
_ratings[ii] = record != null ?
new Rating(record.rating, record.experience) : new Rating();
@@ -168,11 +168,18 @@ public abstract class RatingManagerDelegate
modified = true;
}
// bail if nothing changed
if (!modified) {
return;
}
// finally persist the result if necessary
// else enumerate our players
final int[] players = new int[_gmgr.getPlayerCount()];
for (int ii = 0; ii < players.length; ii ++) {
players[ii] = _gmgr.getPlayerPersistentId(_gmgr.getPlayer(ii));
}
// and finally persist the result
final int gameId = _gmgr.getGameConfig().getGameId();
CrowdServer.invoker.postUnit(new Invoker.Unit() {
public boolean invoke () {
@@ -180,9 +187,8 @@ public abstract class RatingManagerDelegate
for (int ii = 0; ii < _ratings.length; ii ++) {
// for each player, update or create the rating record
// TODO: reorganize things so this can be a single db request?
_repo.setRating(
gameId, _gmgr.getPlayerName(ii),
_ratings[ii].rating, _ratings[ii].experience);
_repo.setRating(gameId, players[ii], _ratings[ii].rating,
_ratings[ii].experience);
}
return true;
@@ -202,23 +208,6 @@ public abstract class RatingManagerDelegate
});
}
/**
* Return the minimum time (in seconds) a game must've lasted for it to count towards rating.
*/
protected abstract int minimumRatedDuration ();
/**
* Return a reference to the {@link RatingRepository} instance we should use to persist.
*/
protected abstract RatingRepository getRatingRepository ();
/**
* Optionally store update ratings in memory e.g. in the user object.
*
* This method is called on the dobj thread.
*/
protected abstract void updateRatingInMemory (int gameId, Name playerName, Rating rating);
/**
* Computes a player's updated rating using a modified version of the FIDE/ELO system.
* The rating adjustment is computed for the player versus each opponent individually and
@@ -317,6 +306,24 @@ public abstract class RatingManagerDelegate
}
}
/**
* Return the minimum time (in seconds) a game must've lasted for it to count towards rating.
*/
protected abstract int minimumRatedDuration ();
/**
* Return a reference to the {@link RatingRepository} instance we should use to persist.
*/
protected abstract RatingRepository getRatingRepository ();
/**
* Optionally store update ratings in memory e.g. in the user object.
*
* This method is called on the dobj thread.
*/
protected abstract void updateRatingInMemory (int gameId, Name playerName, Rating rating);
/** An appropriately casted reference to our GameManager. */
protected GameManager _gmgr;
@@ -31,30 +31,30 @@ import com.samskivert.jdbc.depot.clause.Where;
import com.samskivert.jdbc.depot.operator.Logic.*;
import com.samskivert.jdbc.depot.operator.Conditionals.*;
import com.threerings.util.Name;
/**
* Handles the persistent storage of per-user per-game ratings.
*/
public abstract class RatingRepository extends DepotRepository
public class RatingRepository extends DepotRepository
{
/**
* Users are indexed by integer. It is the responsibility of the subclasser to implement
* an injective mapping of {@link Name} instance to integer here.
* Initialize the {@link RatingRepository}.
*/
public abstract int mapNameToId (Name player);
public RatingRepository(ConnectionProvider conprov)
{
super(conprov);
}
/**
* Loads the rating for the given player for the given game and returns it as a
* {@link RatingRecord} object, or null if the player has no previous rating for the game.
*/
public RatingRecord getRating (int gameId, Name player)
public RatingRecord getRating (int gameId, int playerId)
throws PersistenceException
{
return load(
RatingRecord.class,
RatingRecord.GAME_ID, gameId,
RatingRecord.PLAYER_ID, mapNameToId(player));
RatingRecord.PLAYER_ID, playerId);
}
/**
@@ -62,44 +62,32 @@ public abstract class RatingRepository extends DepotRepository
* them as a list of {@link RatingRecord} objects. The size of this list is no less than zero
* and no greater than the number of given players.
*/
public List<RatingRecord> getRatings (int gameId, Name... players)
public List<RatingRecord> getRatings (int gameId, Integer... players)
throws PersistenceException
{
Comparable[] idArr = new Comparable[players.length];
for (int ii = 0; ii < idArr.length; ii ++) {
idArr[ii] = mapNameToId(players[ii]);
}
return findAll(
RatingRecord.class,
new Where(new And(
new Equals(RatingRecord.GAME_ID, gameId),
new In(RatingRecord.PLAYER_ID, idArr))));
new In(RatingRecord.PLAYER_ID, players))));
}
/**
* Fetch and return all the registered {@link RatingRecord} rows for the given player.
*/
public List<RatingRecord> getRatings (Name player)
public List<RatingRecord> getRatings (int playerId)
throws PersistenceException
{
return findAll(RatingRecord.class, new Where(RatingRecord.PLAYER_ID, mapNameToId(player)));
return findAll(RatingRecord.class, new Where(RatingRecord.PLAYER_ID, playerId));
}
/**
* Set the rating and experience for a given player and game. This method will either update
* or create a row.
*/
public void setRating (int gameId, Name player, int rating, int experience)
public void setRating (int gameId, int playerId, int rating, int experience)
throws PersistenceException
{
store(new RatingRecord(gameId, mapNameToId(player), rating, experience));
}
/**
* Initialize the {@link RatingRepository}.
*/
protected RatingRepository(ConnectionProvider conprov)
{
super(conprov);
store(new RatingRecord(gameId, playerId, rating, experience));
}
}