|
@@ -2,15 +2,13 @@ package com.incubator.game.room;
|
|
|
|
|
|
import com.incubator.common.log4j.Log4jUtil;
|
|
|
import com.incubator.common.util.RandomUtil;
|
|
|
-import com.incubator.game.GGame;
|
|
|
import com.incubator.game.player.Player;
|
|
|
import com.incubator.game.util.ProtoUtil;
|
|
|
import com.incubator.message.proto.CommonProto;
|
|
|
import org.slf4j.Logger;
|
|
|
|
|
|
import java.util.*;
|
|
|
-import java.util.concurrent.ConcurrentHashMap;
|
|
|
-import java.util.concurrent.LinkedBlockingQueue;
|
|
|
+import java.util.concurrent.*;
|
|
|
|
|
|
/**
|
|
|
* 房间 管理类
|
|
@@ -20,6 +18,12 @@ public class RoomManager {
|
|
|
protected Logger logger = Log4jUtil.getLogger(getClass());
|
|
|
|
|
|
private static RoomManager instance;
|
|
|
+ /** 房间对象池 **/
|
|
|
+ public Queue<Room> roomPool;
|
|
|
+ /** 最大空闲房间数量 **/
|
|
|
+ private int maxIdleRooms;
|
|
|
+ /** 房间清理线程 **/
|
|
|
+ private ScheduledExecutorService cleaner;
|
|
|
|
|
|
/** 房间缓存 [key:房间类型, value:房间实例] **/
|
|
|
public Map<Integer, Room> roomMap = new ConcurrentHashMap<>();
|
|
@@ -33,9 +37,57 @@ public class RoomManager {
|
|
|
|
|
|
/**
|
|
|
* 初始化
|
|
|
+ *
|
|
|
+ * @param maxIdleRooms 最大空闲房间数量
|
|
|
*/
|
|
|
- public void init() {
|
|
|
+ public void init(int maxIdleRooms) {
|
|
|
logger.info("初始化房间服务...");
|
|
|
+ this.roomPool = new ConcurrentLinkedQueue<>();
|
|
|
+ this.maxIdleRooms = maxIdleRooms;
|
|
|
+ this.cleaner = Executors.newSingleThreadScheduledExecutor();
|
|
|
+ // 定期清理空闲房间
|
|
|
+ this.cleaner.scheduleAtFixedRate(this::cleanIdleRooms, 10, 30, TimeUnit.SECONDS);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取房间对象
|
|
|
+ *
|
|
|
+ * @param roomType
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ public Room acquireRoom(int roomType) {
|
|
|
+ Room room = roomPool.poll();
|
|
|
+ if (room == null) {
|
|
|
+ // 创建指定类型的房间
|
|
|
+ room = RoomFactory.createRoom(roomType);
|
|
|
+ }
|
|
|
+ return room;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 定期清理空闲房间
|
|
|
+ */
|
|
|
+ private void cleanIdleRooms() {
|
|
|
+ while (roomPool.size() > maxIdleRooms) {
|
|
|
+ Room room = roomPool.poll();
|
|
|
+ if (room != null) {
|
|
|
+ // 销毁房间,释放资源
|
|
|
+ room.destroy();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 关闭对象池
|
|
|
+ */
|
|
|
+ public void shutdown() {
|
|
|
+ cleaner.shutdownNow();
|
|
|
+ roomPool.forEach(Room::destroy);
|
|
|
+ roomPool.clear();
|
|
|
+ }
|
|
|
+
|
|
|
+ public int getAvailableRooms() {
|
|
|
+ return roomPool.size();
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -84,40 +136,6 @@ public class RoomManager {
|
|
|
return null;
|
|
|
}
|
|
|
|
|
|
- /**
|
|
|
- * 获取房间对象
|
|
|
- *
|
|
|
- * @param roomType
|
|
|
- * @return
|
|
|
- */
|
|
|
- private Room acquireRoom(int roomType) {
|
|
|
- LinkedBlockingQueue<Room> pool = GGame.roomPool.computeIfAbsent(roomType, k -> new LinkedBlockingQueue<>(GGame.MAX_ROOM_POOL_SIZE));
|
|
|
- Room room = pool.poll(); // 尝试从池中取一个对象
|
|
|
- if (room == null) {
|
|
|
- room = RoomFactory.createRoom(roomType); // 创建指定类型的房间
|
|
|
- }
|
|
|
- return room;
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 释放房间对象
|
|
|
- *
|
|
|
- * @param room
|
|
|
- * @param roomType
|
|
|
- */
|
|
|
- private void releaseRoom(Room room, int roomType) {
|
|
|
- if (room == null) {
|
|
|
- return;
|
|
|
- }
|
|
|
- // 清理房间对象状态
|
|
|
- room.reset();
|
|
|
- LinkedBlockingQueue<Room> pool = GGame.roomPool.computeIfAbsent(roomType, k -> new LinkedBlockingQueue<>(GGame.MAX_ROOM_POOL_SIZE));
|
|
|
- // 如果池未满,则放回池中
|
|
|
- if (pool.size() < GGame.MAX_ROOM_POOL_SIZE) {
|
|
|
- pool.offer(room);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
/**
|
|
|
* 创建房间
|
|
|
*
|
|
@@ -136,22 +154,6 @@ public class RoomManager {
|
|
|
return room;
|
|
|
}
|
|
|
|
|
|
- /**
|
|
|
- * 销毁房间
|
|
|
- *
|
|
|
- * @param roomId
|
|
|
- */
|
|
|
- public void destroyRoom(int roomId, int roomType) {
|
|
|
- // todo 广播房间解散
|
|
|
-
|
|
|
- // 移除缓存
|
|
|
- Room room = this.roomMap.remove(roomId);
|
|
|
- if (room != null) {
|
|
|
- // 将房间对象归还对象池
|
|
|
- this.releaseRoom(room, roomType);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
/**
|
|
|
* 加入房间
|
|
|
*
|