Union Ranking Manager
/**
* Copyright uwi ( http://wonderfl.net/user/uwi )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/1u8m
*/
package {
import flash.utils.ByteArray;
import flash.display.Sprite;
import flash.text.TextField;
import flash.events.Event;
public class FlashTest extends Sprite {
private var _tf : TextField;
private var _urm : UnionRankingManager;
public function FlashTest() {
_tf = new TextField();
addChild(_tf);
_tf.width = 465;
_tf.height = 465;
_urm = new UnionRankingManager("testHighscore", 10);
_urm.addEventListener(UnionRankingManager.UPDATE, onURMInit);
}
private function onURMInit(e : Event) : void
{
_urm.removeEventListener(UnionRankingManager.UPDATE, onURMInit);
// _urm.clearHighscore();
_tf.appendText("before:\n");
var hl : Array = _urm.getHighscoreList();
for each(var o : Object in hl){
var d : Date = new Date();
d.setTime(o.date);
_tf.appendText(o.name + "\t" + o.score + "\t" + d + "\n");
}
var score : int = Math.random() * 100000;
_tf.appendText("insertedScore : " + score + " rank : " + _urm.getRank(score) + "\n");
var u : int = _urm.insertHighscore(score, "test");
_urm.addEventListener(UnionRankingManager.UPDATE, function(e : Event) : void
{
_tf.appendText("after:\n");
_urm.removeEventListener(UnionRankingManager.UPDATE, arguments.callee);
var hl : Array = _urm.getHighscoreList();
for each(var o : Object in hl){
var d : Date = new Date();
d.setTime(o.date);
_tf.appendText(o.name + "\t" + o.score + "\t" + d + "\n");
}
_urm.leave();
});
}
}
}
import flash.events.EventDispatcher;
import net.user1.reactor.*;
import com.adobe.serialization.json.*;
import flash.events.Event;
class UnionRankingManager extends EventDispatcher
{
private static const ATTR_NAME : String = "RANK";
public static const UPDATE : String = RoomEvent.SYNCHRONIZE;
private var _reactor : Reactor;
private var _rm : RoomManager;
private var _room : Room = null;
private var _roomName : String;
private var _limRank : uint = 5;
public function UnionRankingManager(roomName : String, limRank : uint)
{
_reactor = new Reactor();
_reactor.addEventListener(ReactorEvent.READY, onReactorReady);
_reactor.connect("tryunion.com", 9100);
_limRank = limRank;
_roomName = roomName;
}
// roomの作成
private function onReactorReady(e : ReactorEvent) : void
{
var rs : RoomSettings = new RoomSettings();
rs.dieOnEmpty = false;
_rm = _reactor.getRoomManager();
_room = _rm.createRoom(_roomName, rs);
_rm.addEventListener(RoomManagerEvent.CREATE_ROOM_RESULTS, onCreateRoomResults);
}
private function onCreateRoomResults(e : RoomManagerEvent) : void
{
_rm.removeEventListener(RoomManagerEvent.CREATE_ROOM_RESULTS, onCreateRoomResults);
_room.join();
_room.addEventListener(RoomEvent.SYNCHRONIZE, onRoomSynchronize);
}
private function onRoomSynchronize(e : RoomEvent) : void
{
_room.removeEventListener(e.type, onRoomSynchronize);
dispatchEvent(new Event(UPDATE));
}
// ハイスコアリストを取得
public function getHighscoreList() : Array
{
if(_room == null || !_room.clientIsInRoom())return null;
var val : String = _room.getAttribute(ATTR_NAME);
if(val == null)return [];
var jd : JSONDecoder = new JSONDecoder(val);
return jd.getValue();
}
// ハイスコアリストを生(JSON)で取得
public function getHighscoreJSON() : String
{
if(_room == null || !_room.clientIsInRoom())return null;
return _room.getAttribute(ATTR_NAME);
}
// ハイスコアをクリア。ローカルに反映させるにはupdateしなければならない。
public function clearHighscore() : void
{
if(_room == null || !_room.clientIsInRoom())return;
_room.deleteAttribute(ATTR_NAME);
}
// ハイスコアを挿入。戻り値は順位。
public function insertHighscore(score : Number, name : String) : int
{
if(_room == null || !_room.clientIsInRoom())return -2;
var hl : Array = getHighscoreList();
var rank : int = getRank(score);
if(rank >= _limRank)return -1;
hl.splice(rank, 0, {score : score, name : name, date : new Date().time});
if(hl.length > _limRank){
hl = hl.slice(0, _limRank);
}
setHighscore(hl);
return rank;
}
// 部屋を出る
public function leave() : void
{
if(_room == null || !_room.clientIsInRoom())return;
_room.leave();
}
// 部屋を消す
public function remove() : void
{
if(_room == null || !_room.clientIsInRoom())return;
_room.remove();
}
// ハイスコアリストをセット
private function setHighscore(highscoreList : Array) : void
{
if(_room == null || !_room.clientIsInRoom())return;
var je : JSONEncoder = new JSONEncoder(highscoreList);
_room.setAttribute(ATTR_NAME, je.getString(), true, true);
_room.addEventListener(RoomEvent.UPDATE_ROOM_ATTRIBUTE, onRoomSynchronize);
}
// 指定スコアのハイスコアリスト内でのランクを取得
public function getRank(score : Number) : int
{
var hl : Array = getHighscoreList();
if(hl.length == 0)return 0;
var ind : int = binarySearch(hl, score, function(s : Number, o : Object) : int {
return -(s - o.score);
});
return ind >= 0 ? (ind + 1) : (-ind - 1);
}
// バイナリサーチ
private function binarySearch(a : Array, v : Number, comp : Function) : int
{
var s : uint = 0;
var g : uint = a.length;
if(comp(v, a[g-1]) > 0)return -g-1;
var c0 : int = comp(v, a[0]);
if(c0 < 0)return -1;
if(c0 == 0)return 0;
do{
var m : uint = (s + g) >> 1;
var cm : int = comp(v, a[m]);
if(cm == 0)return m;
if(cm < 0){
g = m;
}else{
s = m;
}
}while(g - s > 1);
return -s - 2;
}
}