package mapcfg
/*******************************************************************************
Author: Yigui Lu (卢益贵)
Contact WX/QQ: 48092788
Blog: https://blog.csdn.net/guestcode
Creation by: 2024-3-16
*******************************************************************************/
// 本配置单元可以作为配置模板加载所有配置
import (
"cfgload/queue"
"io/ioutil"
"log"
"time"
)
const ModuleName = "地图配置模块"
// 地图配置项,一个对应一个
type Item struct {
Name string // 地图名
ResName string // 地址资源名
ResData []byte // 资源数据
Attrs []int // 地图属性
}
// 外部类型:地图配置类
type Cfg struct {
Item *Item // 真正的配置对象是Item
LoadCount int // 加载次数,演示用
onReloads []func() // 触发重载回调,部分场景需求用
}
func (c *Cfg) AddOnReload(onReload func()) {
c.onReloads = append(c.onReloads, onReload)
}
// 配置表
type cfgs = map[string]*Cfg
// 配置表(全局变量/外部接口,仅主线程调用无需同步)
var Cfgs cfgs
// 配置异步加载协程
var loadcount int
// 异步加载/重载通用函数,无需两者区分而额外编写代码
func loadFunc(ch chan bool) {
for {
// 等待加载通知
<-ch
// 以下在加载线程中执行 -->
isReload := Cfgs != nil
loadcount++
if isReload {
log.Println("地图配置模块(加载线程) => 正在重载......", loadcount)
} else {
log.Println("地图配置模块(加载线程) => 正在加载......")
}
var items []*Item
for {
// 模拟配置文件加载过程
item := &Item{
Name: "南天门",
ResName: "res001.map",
}
item.ResData, _ = ioutil.ReadFile(item.ResName)
items = append(items, item)
break // 仅加载一行
}
// <-- 以上在加载线程中执行
// 匿名函数将在主线程执行,达到线程同步目的
onModuleLoadedInMain := func() {
if Cfgs == nil {
// 首次加载
Cfgs = make(cfgs)
}
for _, item := range items {
cfg := Cfgs[item.Name]
if cfg == nil {
// 新增配置
cfg = &Cfg{}
cfg.Item = item
cfg.LoadCount = 1
Cfgs[item.Name] = cfg
} else {
// 替换旧的配置
cfg.Item = item
cfg.LoadCount++
// 在主线程调用重载通知回调(只有部分场景需求才需要通知)
for _, onReload := range cfg.onReloads {
onReload()
}
}
}
}
if isReload {
log.Println("地图配置模块(加载线程) => 重载完毕", loadcount)
} else {
log.Println("地图配置模块(加载线程) => 加载完毕")
}
// 给主消息队列压栈
// 主线程会调用onModuleLoadedInMain执行,达到线程同步目的
queue.MainQ <- onModuleLoadedInMain
// 首次加载,触发事件告诉主线程模块加载完毕
if !isReload {
queue.TriggerEvent(ModuleName)
}
}
}
func reloadTrigger(ch chan bool) {
// 模拟5秒钟触发一次重载请求
for {
ch <- true
time.Sleep(time.Second * 5)
}
}
func init() {
ch := make(chan bool)
go loadFunc(ch)
go reloadTrigger(ch)
}
没有合适的资源?快使用搜索试试~ 我知道了~
温馨提示
游戏服务端配置“热更”终极方案(golang/ygluu/卢益贵) 众所周知,游戏服务端配置信息热更有几大问题: 1、因配置对象的指针被场景对象引用而导致热更复杂度提高 2、信息量大的配置表热更导致游戏卡顿、玩家闪断 3、一般重载后的配置信息仅影响重载后新创建的对应场景对象,不能影响已存在的场景对象 4、在高度解耦的模块化开发模式下导致热更复杂度提高 本示例代码将使用通用方法来演示在“高度解耦、模块化、模板化”的开发模式下对上述问题的解决方案。
资源推荐
资源详情
资源评论
收起资源包目录
cfgload.rar (4个子文件)
mapcfg
mapcfg.go 3KB
queue
queue.go 759B
mapmgr
mapmgr.go 2KB
main.go 515B
共 4 条
- 1
资源评论
ygluu
- 粉丝: 226
- 资源: 39
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功