当前位置: 首页 > article >正文

【游戏中orika完成一个Entity的复制及其Entity异步落地的实现】 1.ctrl+shift+a是飞书下的截图 2.落地实现

一、orika工具使用

1)工具类

package com.xinyue.game.utils;

import ma.glasnost.orika.MapperFactory;
import ma.glasnost.orika.impl.DefaultMapperFactory;

/**
 * @author 王广帅
 * @since 2022/2/8 22:37
 */
public class XyBeanCopyUtil {
    private static MapperFactory mapperFactory = new DefaultMapperFactory.Builder().build();

    /**
     * 将对象S的数据,复制到对象T中
     *
     * @param data  要复制的数据对象
     * @param clazz 新的接收数据的对象class
     * @param <S>
     * @param <T>
     * @return
     */
    public static <S, T> T copyObj(S data, Class<T> clazz) {
        return mapperFactory.getMapperFacade().map(data, clazz);
    }
}

2)测试

package com.xinyue.game.utils;

import com.xinyue.game.utils.model.TestUser;
import org.testng.Assert;
import org.testng.annotations.Test;

/**
 * @author 王广帅
 * @since 2022/2/13 19:38
 */
public class XyBeanCopyUtilTest {

    @Test
    public void testCopyObj() {
        TestUser testUser = new TestUser();
        String name = "aaa";
        testUser.setName(name);
        String key = "1";
        String value = "北京";
        testUser.getAddressMap().put(key, value);

        TestUser newUser = XyBeanCopyUtil.copyObj(testUser, TestUser.class);
        Assert.assertEquals(newUser.getName(), name);
        Assert.assertEquals(newUser.getAddressMap().get(key), testUser.getAddressMap().get(key));
    }
}

可以看出是深拷贝!!! 

我们在开发中,经常需要异步线程进行数据库的落地,这里就用到了深拷贝技术,我们无需考虑List,因为游戏中都是单个实体进行落地的。

二、游戏中定时落地实现

1.时机1:缓存中移除时

    @PostConstruct
    public void init() {
        roleCache = CacheBuilder.newBuilder().expireAfterAccess(Duration.ofMinutes(gameServerConfig.getExpireOfAccess()))
                .initialCapacity(1000).maximumSize(gameServerConfig.getMaxCacheSize()).removalListener(new RemovalListener<String, PlayerEntity>() {
                    @Override
                    public void onRemoval(RemovalNotification<String, PlayerEntity> notification) {
                        logger.info("角色被从内存中移除,更新一次到数据库,playerId:{}", notification.getKey());
                        PlayerEntity playerEntity = notification.getValue();
                        flushPlayer(playerEntity);
                    }
                }).build();
    }

 2.时机2:下线时

    @EventListener
    public void logoutEvent(LoginOutEvent event) {
        // 用户下线时,刷新一下缓存
        this.flushPlayer(event.getPlayerId());
        logger.info("用户下线,刷新缓存,playerId:{},threadId:{}", event.getPlayerId(), Thread.currentThread().getId());
    }

3.落地实现

    public void flushPlayer(String roleId) {
        PlayerEntity playerEntity = this.getPlayerIfPresent(roleId);
        this.flushPlayer(playerEntity);
    }

    private void flushPlayer(PlayerEntity playerEntity) {
        if (playerEntity != null) {
            // 深拷贝出来当前对象
            PlayerEntity newPlayerEntity = XyBeanCopyUtil.copyObj(playerEntity, PlayerEntity.class);


            // 异步线程进行落地
            gameAsyncTaskService.execute(String.valueOf(playerEntity.getPlayerId()), "更新role信息", () -> {
                this.daoPlayerService.updatePlayer(newPlayerEntity);
            });
        }
    }


http://www.kler.cn/a/443726.html

相关文章:

  • 前端下载文件的几种方式使用Blob下载文件
  • C++中的字符串实现
  • UG NX二次开发(C#)-机电概念设计-UIStyler中selection块选择信号等对象的过滤器设置
  • 1 软件工程——概述
  • OpenHarmony的分布式服务框架介绍与实现解析
  • Java字符串的|分隔符转List实现方案
  • 多个图片转换为PDF文件
  • 时空AI赋能低空智能科技创新
  • IAR中如何而将定义的数组放在指定的位置
  • 【硬件IIC】stm32单片机利用硬件IIC驱动OLED屏幕
  • C05S09-Keepalive服务架设
  • pytest 小技巧:非测试方法如何使用 pytest fixture
  • 笔记--(Shell脚本04)、循环语句与函数
  • 多功能护照阅读器港澳通行证阅读机RS232串口主动输出协议,支持和单片机/Linux对接使用
  • Midjourney教程之生成同一角色的不同姿势和服装
  • Docker 容器网络问题排查与最佳实践 - PushGateway 部署案例分析
  • 详细分析:AG32 MCU与STM32/GD32的区别
  • Android 折叠屏问题解决 - 展开后布局未撑开
  • 【图像配准】方法总结
  • HarmonyOS NEXT 应用开发实战:音乐播放器的完整实现
  • Vue|scoped样式
  • mapboxGL中室内地图的实现
  • PowerMILL 客制化宏 - 命令关键字
  • 应用如何借用manifestxml追加gid权限
  • PostgreSql-学习06-libpq之同步命令处理
  • go 自己写序列化函数不转义