This commit is contained in:
meixiongfeng 2022-12-14 10:08:27 +08:00
commit f3eb7b6144
12 changed files with 476 additions and 79 deletions

View File

@ -58,7 +58,7 @@ func (f *ArenaScene) Run(ai lib.IRobot) (err error) {
ai.Stop()
return
}
time.Sleep(time.Second * 5)
Sleep(time.Second*3, time.Second*5)
if code = ai.SendMsg("arena", "challengereward", &pb.ArenaChallengeRewardReq{
Iswin: true,
Isai: v.Isai,
@ -74,7 +74,7 @@ func (f *ArenaScene) Run(ai lib.IRobot) (err error) {
ai.Stop()
return
}
time.Sleep(time.Second * 2)
Sleep(time.Second*1, time.Second*3)
}
return
}

View File

@ -51,7 +51,7 @@ func (f *ChatScene) Run(ai lib.IRobot) (err error) {
ai.Stop()
return
}
time.Sleep(time.Second * 1)
Sleep(time.Second*1, time.Second*3)
}
}

12
busi/core.go Normal file
View File

@ -0,0 +1,12 @@
package busi
import (
"math/rand"
"time"
)
func Sleep(min, max time.Duration) {
ulit := int64(max - min)
t := time.Duration(rand.Int63n(ulit)) + min
time.Sleep(t)
}

80
busi/mfantasy.go Normal file
View File

@ -0,0 +1,80 @@
package busi
import (
"time"
"legu.airobot/lib"
"legu.airobot/pb"
)
//竞技场场景
var _ lib.IScene = (*MfantasyScene)(nil)
type MfantasyScene struct {
lib.Action
}
func (f *MfantasyScene) Info() lib.SceneInfo {
return lib.SceneInfo{
Name: "秘境",
Desc: "秘境测试",
}
}
func (f *MfantasyScene) Run(ai lib.IRobot) (err error) {
var (
code pb.ErrorCode
herolistrsp *pb.HeroListResp
mflist *pb.MoonfantasyGetListResp = &pb.MoonfantasyGetListResp{}
battlereq *pb.MoonfantasyBattleResp = &pb.MoonfantasyBattleResp{}
)
if herolist := ai.Get("hero.list"); herolist == nil {
ai.Stop()
return
} else {
herolistrsp = herolist.(*pb.HeroListResp)
if herolistrsp.List == nil || len(herolistrsp.List) == 0 {
ai.Stop()
return
}
}
if code = ai.SendMsg("gm", "cmd", &pb.GMCmdReq{
Cmod: "bingo:moon,1",
}, &pb.GMCmdResp{}); code != pb.ErrorCode_Success {
ai.Stop()
}
if code = ai.SendMsg("moonfantasy", "getlist", &pb.MoonfantasyGetListReq{}, mflist); code != pb.ErrorCode_Success {
ai.Stop()
}
for _, v := range mflist.Dfantasys {
if code = ai.SendMsg("moonfantasy", "battle", &pb.MoonfantasyBattleReq{
Mid: v.Monster,
Battle: &pb.BattleFormation{
Leadpos: 0,
Format: []string{herolistrsp.List[0].Id},
},
}, battlereq); code != pb.ErrorCode_Success {
ai.Stop()
}
Sleep(time.Second*3, time.Second*5)
if code = ai.SendMsg("moonfantasy", "receive", &pb.MoonfantasyReceiveReq{
Report: &pb.BattleReport{
Info: battlereq.Info,
Costtime: 1,
Process: []byte{123},
Completetask: []int32{},
},
}, &pb.MoonfantasyReceiveResp{}); code != pb.ErrorCode_Success {
ai.Stop()
return
}
Sleep(time.Second, time.Second*3)
}
return
}

52
busi/pay.go Normal file
View File

@ -0,0 +1,52 @@
package busi
import (
"time"
"legu.airobot/lib"
"legu.airobot/pb"
)
//竞技场场景
var _ lib.IScene = (*PayScene)(nil)
type PayScene struct {
lib.Action
}
func (f *PayScene) Info() lib.SceneInfo {
return lib.SceneInfo{
Name: "支付",
Desc: "充值模拟",
}
}
func (f *PayScene) Run(ai lib.IRobot) (err error) {
var (
code pb.ErrorCode
)
if code = ai.SendMsg("pay", "dailybuy", &pb.PayDailyBuyReq{
Id: 1,
}, &pb.PayDailyBuyResp{}); code != pb.ErrorCode_Success {
ai.Stop()
return
}
time.Sleep(time.Second)
if code = ai.SendMsg("pay", "dailybuy", &pb.PayDailyBuyReq{
Id: 2,
}, &pb.PayDailyBuyResp{}); code != pb.ErrorCode_Success {
ai.Stop()
return
}
time.Sleep(time.Second)
if code = ai.SendMsg("privilege", "buyyueka", &pb.PrivilegeBuyYuekaReq{
CID: "yueka_lv1",
}, &pb.PrivilegeBuyYuekaResp{}); code != pb.ErrorCode_Success {
ai.Stop()
return
}
time.Sleep(time.Second)
return
}

145
lib/ai.go
View File

@ -3,6 +3,10 @@ package lib
import (
"bytes"
"fmt"
"os"
"path/filepath"
"sort"
"strings"
"sync"
"sync/atomic"
"time"
@ -12,13 +16,15 @@ import (
)
type myAI struct {
robots []*Robot
scenes []*scene
iscenes []IScene
tickets Tickets //票池
useCount uint32 //计数(压入的用户数)
lock sync.Mutex //
config *storage.Config //配置
robots []*Robot
scenes []*scene
iscenes []IScene
tickets Tickets //票池
useCount uint32 //计数(压入的用户数)
useCountTotal uint32 //总数
lock sync.Mutex //合并数据锁
config *storage.Config //配置
ReportMap map[int]map[string]*Statistics //测试报告 key1:场景 key2:协议
}
func NewAI(aip AIParam) (*myAI, error) {
@ -27,9 +33,10 @@ func NewAI(aip AIParam) (*myAI, error) {
}
ai := &myAI{
scenes: make([]*scene, 0),
config: aip.Config,
iscenes: aip.Scenes,
scenes: make([]*scene, 0),
config: aip.Config,
iscenes: aip.Scenes,
ReportMap: make(map[int]map[string]*Statistics),
}
if err := ai.init(); err != nil {
@ -56,7 +63,7 @@ func (m *myAI) init() error {
return nil
}
func (m *myAI) appendRobot(robot *Robot) {
func (m *myAI) AppendRobot(robot *Robot) {
defer m.lock.Unlock()
m.lock.Lock()
m.robots = append(m.robots, robot)
@ -67,7 +74,7 @@ func (m *myAI) Start() bool {
logrus.Warn("还未设置场景")
return false
}
logrus.Info("测试中...")
go func() {
for {
m.tickets.Take()
@ -79,12 +86,27 @@ func (m *myAI) Start() bool {
atomic.AddUint32(&m.useCount, 1)
robot := NewRobot(m.config)
robot.SetScenes(m.iscenes)
m.appendRobot(robot)
m.AppendRobot(robot)
robot.Start()
atomic.AddUint32(&m.useCountTotal, 1)
}()
}
}()
go func() {
start := time.Now()
for {
total := atomic.LoadUint32(&m.useCountTotal)
if total == m.config.Global.UserCountTotal {
elipse := time.Since(start)
logrus.Info("开始生成测试报告")
m.MergeResult()
m.genReport(elipse)
break
}
}
}()
return true
}
@ -92,6 +114,101 @@ func (m *myAI) Stop() {
}
func (m *myAI) ShowResult() {
func (m *myAI) MergeResult() {
m.lock.Lock()
defer m.lock.Unlock()
n := make(map[int]map[string]*Statistics)
for _, r := range m.robots {
if len(n) == 0 {
n = r.ReportMap
} else {
x := n //已存在的
y := r.ReportMap //将要合并的
for i, v := range x {
for j, w := range y {
//场景相同
if i == j {
for k, a := range v {
for l, b := range w {
//判断协议是否相同
if k == l {
statis := &Statistics{}
statis.ElapseTotal = time.Duration(int64(a.ElapseTotal + b.ElapseTotal))
statis.AvgElapse = time.Duration(int64(a.AvgElapse+b.AvgElapse) / int64(2))
statis.CallCount = (a.CallCount + b.CallCount)
max := a.MaxElapse
if max < b.MaxElapse {
max = b.MaxElapse
}
statis.MaxElapse = max
min := a.MinElapse
if min > b.MinElapse {
min = b.MinElapse
}
statis.MinElapse = min
statis.Route = a.Route
statis.SceneName = a.SceneName
if n[i][k] == nil {
n[i] = make(map[string]*Statistics)
}
n[i][k] = statis
} else {
if _, ok := n[i][k]; !ok {
n[i][k] = a
}
if _, ok := n[i][l]; !ok {
n[i][l] = b
}
}
}
}
} else {
if _, ok := n[i]; !ok {
n[i] = v
}
if _, ok := n[j]; !ok {
n[j] = w
}
}
}
}
}
}
m.ReportMap = n
}
func (m *myAI) genReport(elipse time.Duration) {
var msgs []string
var i []int
for key, _ := range m.ReportMap {
i = append(i, key)
}
sort.Ints(i)
for _, routes := range i {
for r, d := range m.ReportMap[routes] {
msgs = append(msgs, fmt.Sprintf("【%s】协议:%s 调用次数:%d 总耗时:%v 平均耗时:%v 最大耗时:%v 最小耗时:%v",
d.SceneName, r, d.CallCount, d.ElapseTotal.String(), d.AvgElapse.String(), d.MaxElapse.String(), d.MinElapse.String()))
}
}
record := strings.Join(msgs, "\n")
var buf bytes.Buffer
buf.WriteString("测试报告\n")
buf.WriteString(fmt.Sprintf("用户总数:%d 单次投放人数:%d 投放间隔时间:%ds 共计时间:%s\n",
m.config.Global.UserCountTotal, m.config.Global.UserCount, m.config.Global.IntervalS, elipse.String()))
buf.WriteString(record)
buf.WriteString("\n------------------------------------------------------------------------------------------------------\n")
// logrus.WithField("res", buf.String()).Debug("报告内容")
file, err := os.OpenFile(filepath.Join("./", "report.log"), os.O_TRUNC|os.O_CREATE, os.ModePerm)
if err != nil {
logrus.Error(err)
}
defer file.Close()
if _, err := file.WriteString(buf.String()); err != nil {
logrus.Error(err)
}
logrus.Info("已生成测试报告")
}

View File

@ -26,10 +26,12 @@ type SceneInfo struct {
}
type CallResult struct {
ID int64 // ID。
MainType string
SubType string
Elapse time.Duration // 耗时。
ID int64 // ID
SceneName string
MainType string
SubType string
Elapse time.Duration // 耗时
Num int
}
type Statistics struct {
@ -39,6 +41,7 @@ type Statistics struct {
AvgElapse time.Duration //平均耗时
CallCount int64 //调用次数
Route string //协议名称
SceneName string //场景名称
}
const (

View File

@ -32,16 +32,19 @@ type IRobot interface {
type Robot struct {
IStore
scene IScene //场景
account string
sid string
conn *websocket.Conn
data map[string]interface{} //机器人缓存数据
status uint32 //状态
lock sync.Mutex //
sceneQueue *Queue[IScene] //场景队列
config *storage.Config //配置
resultCh chan *CallResult //请求结果通道
sceneResultCh chan *CallResult //场景结果通道
data map[string]interface{} //机器人缓存数据
status uint32 //状态
lock sync.Mutex //数据缓存锁
sceneQueue *Queue[IScene] //场景队列
config *storage.Config //配置
resultCh chan *CallResult //请求结果通道
sceneResultCh chan *CallResult //场景结果通道
ReportMap map[int]map[string]*Statistics //测试报告 key1:场景序号 key2:协议
elipseTotal time.Duration
}
func NewRobot(config *storage.Config) *Robot {
@ -51,6 +54,7 @@ func NewRobot(config *storage.Config) *Robot {
config: config,
resultCh: make(chan *CallResult, 100),
sceneResultCh: make(chan *CallResult, 50),
ReportMap: make(map[int]map[string]*Statistics),
}
robot.Store("sid", config.Global.SId)
return robot
@ -76,11 +80,17 @@ func (r *Robot) SendMsg(mainType, subType string, req proto.Message, rsp proto.M
defer func() {
t := time.Since(start)
logrus.WithFields(logrus.Fields{"MainType": mainType, "SubType": subType, "rsp": rsp, "since": t.String()}).Debug("接收消息")
var name string
if r.scene != nil {
name = r.scene.Info().Name
}
// 发送请求结果
r.SendResult(&CallResult{
MainType: mainType,
SubType: subType,
Elapse: t,
SceneName: name,
MainType: mainType,
SubType: subType,
Elapse: t,
Num: r.getSortNum(name),
})
}()
@ -136,13 +146,31 @@ func (a *Robot) SetScenes(scenes []IScene) {
for _, v := range scenes {
info := v.Info()
if conf.Name == info.Name {
a.sceneQueue.Add(v)
continue
if conf.Loop == 0 || conf.Loop == 1 {
a.sceneQueue.Add(v)
continue
} else if conf.Loop > 1 {
for i := int32(0); i < conf.Loop; i++ {
a.sceneQueue.Add(v)
}
continue
}
}
}
}
}
// 根据场景名称获取顺序号
func (a *Robot) getSortNum(name string) int {
var num int
for _, v := range a.config.Scenes {
if v.Name == name {
return v.Num
}
}
return num
}
func (m *Robot) Start() bool {
if len(m.sceneQueue.List()) == 0 {
logrus.Warn("没有设置场景队列")
@ -185,10 +213,12 @@ func (m *Robot) syncCall() {
for {
scene, err := m.sceneQueue.Pop()
if err != nil {
logrus.WithField("err", err).Warn("所有场景执行结束")
logrus.WithField("err", err).Debug("所有场景执行结束")
m.prepareToStop()
return
}
m.scene = scene
info := m.scene.Info()
start := time.Now()
//这里执行会花很长时间
@ -197,18 +227,17 @@ func (m *Robot) syncCall() {
break
}
elapsedTime := time.Since(start)
info := scene.Info()
m.elipseTotal += elapsedTime
logrus.WithField("t", elapsedTime.String()).Debug("场景【" + info.Name + "】执行完毕耗时统计")
//结束
// m.prepareToStop()
//显示场景结果
m.ShowResult()
m.processResult()
}
}
func (m *Robot) prepareToStop() {
atomic.CompareAndSwapUint32(&m.status, STATUS_STARTED, STATUS_STOPPING)
logrus.Infof("关闭结果通道...")
logrus.Debug("关闭结果通道...")
close(m.resultCh)
atomic.StoreUint32(&m.status, STATUS_STOPPED)
}
@ -228,27 +257,14 @@ func (m *Robot) SendResult(result *CallResult) bool {
}
}
func (m *Robot) ShowResult() {
func (m *Robot) processResult() {
go func() {
logrus.Debug("开始生成测试报告")
defer logrus.Debug("测试报告生成完成")
routes := make(map[string]*Statistics)
defer m.lock.Unlock()
m.lock.Lock()
for r := range m.resultCh {
head := fmt.Sprintf("%s.%s", r.MainType, r.SubType)
logrus.WithField("head", head).Debug("读结果")
if len(routes) == 0 {
statis := &Statistics{
Route: head,
ElapseTotal: r.Elapse,
MaxElapse: r.Elapse,
MinElapse: r.Elapse,
CallCount: 1,
}
avg := (statis.MaxElapse + statis.MinElapse) / 2
statis.AvgElapse = avg
routes[head] = statis
} else {
if route, ok := routes[head]; ok {
if routes, ok := m.ReportMap[r.Num]; ok {
if route, y := routes[head]; y {
max := route.MaxElapse
min := route.MinElapse
if r.Elapse > max {
@ -260,6 +276,7 @@ func (m *Robot) ShowResult() {
}
statis := &Statistics{
Route: head,
SceneName: r.SceneName,
ElapseTotal: route.ElapseTotal + r.Elapse,
MaxElapse: max,
MinElapse: min,
@ -271,6 +288,7 @@ func (m *Robot) ShowResult() {
} else {
statis := &Statistics{
Route: head,
SceneName: r.SceneName,
ElapseTotal: r.Elapse,
MaxElapse: r.Elapse,
MinElapse: r.Elapse,
@ -280,26 +298,52 @@ func (m *Robot) ShowResult() {
statis.AvgElapse = avg
routes[head] = statis
}
m.ReportMap[r.Num] = routes
} else {
route := make(map[string]*Statistics)
statis := &Statistics{
Route: head,
SceneName: r.SceneName,
ElapseTotal: r.Elapse,
MaxElapse: r.Elapse,
MinElapse: r.Elapse,
CallCount: 1,
}
avg := (statis.MaxElapse + statis.MinElapse) / 2
statis.AvgElapse = avg
route[head] = statis
m.ReportMap[r.Num] = route
}
}
// 将统计结果写入文件
var msgs []string
for k, v := range routes {
msgs = append(msgs, fmt.Sprintf("协议:%s 调用次数:%d 总耗时:%v 平均耗时:%v 最大耗时:%v 最小耗时:%v",
k, v.CallCount, v.ElapseTotal.String(), v.AvgElapse.String(), v.MaxElapse.String(), v.MinElapse.String()))
}
record := strings.Join(msgs, "\n")
var buf bytes.Buffer
buf.WriteString("测试报告\n")
buf.WriteString(record)
logrus.WithField("res", buf.String()).Debug("报告内容")
if err := ioutil.WriteFile(filepath.Join("./", "report.log"), buf.Bytes(), fs.ModePerm); err != nil {
logrus.WithField("err", err).Error("测试报告")
}
}()
}
// 将统计结果写入文件
// Deprecated
func (m *Robot) genReport(e time.Duration) {
var buf bytes.Buffer
buf.WriteString("测试报告\n")
buf.WriteString(fmt.Sprintf("用户总数:%d 场景总耗时:%s\n",
m.config.Global.UserCountTotal, e.String()))
var msgs []string
for k, routes := range m.ReportMap {
// buf.WriteString(fmt.Sprintf("【%s】\n", k))
for r, d := range routes {
msgs = append(msgs, fmt.Sprintf("【%s】协议:%s 调用次数:%d 总耗时:%v 平均耗时:%v 最大耗时:%v 最小耗时:%v",
k, r, d.CallCount, d.ElapseTotal.String(), d.AvgElapse.String(), d.MaxElapse.String(), d.MinElapse.String()))
}
}
record := strings.Join(msgs, "\n")
buf.WriteString(record)
buf.WriteString("\n------------------------------------------------------------------------------\n")
// logrus.WithField("res", buf.String()).Debug("报告内容")
if err := ioutil.WriteFile(filepath.Join("./", "report.log"), buf.Bytes(), fs.ModePerm); err != nil {
logrus.WithField("err", err).Error("测试报告")
}
}
func (m *Robot) printIgnoredResult(result *CallResult, cause string) {
resultMsg := fmt.Sprintf(
"MainType=%s, SubType=%s, Elapse=%v",

View File

@ -38,6 +38,7 @@ func init() {
&busi.ShopScene{},
&busi.ArenaScene{},
&busi.ReddotScene{},
&busi.PayScene{},
)
}
@ -68,7 +69,6 @@ func setupLogger() (err error) {
logrus.SetLevel(logrus.DebugLevel)
logrus.SetOutput(os.Stdout)
//设置output,默认为stderr,可以为任何io.Writer比如文件*os.File
file, err := os.OpenFile("robot.log", os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0666)
writers := []io.Writer{
file,

View File

@ -11,8 +11,8 @@ type Config struct {
}
type Global struct {
UserCount uint32 `json:"UserCount,omitempty"` //用户数(每次压入的数量)
UserCountTotal uint32 `json:"UserCountTotal,omitempty"` //用户总数(压入的总数)
UserCount uint32 `json:"UserCount,omitempty"` //用户数(每次压入的数量)
UserCountTotal uint32 `json:"UserCountTotal,omitempty"` //用户总数(压入的总数)
SId string `json:"sid,omitempty"` //区服ID
WsAddr string `json:"wsAddr,omitempty"` //websocket addr
IntervalS int32 `json:"intervalS,omitempty"` //间隔时间s每次压入用户的间隔时间
@ -26,6 +26,7 @@ type Scene struct {
Callers []*Caller `json:"callers,omitempty"` //调用器列表
Status uint32 `json:"status,omitempty"` //是否启用 默认0未启用 1是启用
Num int `json:"num,omitempty"` //顺序号
Loop int32 `json:"loop,omitempty"` //循环次数
}
type Caller struct {

View File

@ -6,6 +6,7 @@ import (
"legu.airobot/busi/friend"
"legu.airobot/lib"
"legu.airobot/storage"
)
func TestAction(t *testing.T) {
@ -47,3 +48,76 @@ func TestA(t *testing.T) {
fmt.Println(i)
}
}
func TestMerge(t *testing.T) {
config := &storage.Config{
Global: &storage.Global{UserCountTotal: 2, SId: "dfz", UserCount: 1},
}
ma, _ := lib.NewAI(lib.AIParam{Config: config})
robot1 := lib.NewRobot(config)
robot1.ReportMap = make(map[int]map[string]*lib.Statistics)
robot1.ReportMap[1] = make(map[string]*lib.Statistics)
robot1.ReportMap[1]["user.login"] = &lib.Statistics{
ElapseTotal: 5,
CallCount: 2,
AvgElapse: 2,
MaxElapse: 4,
MinElapse: 2,
Route: "user.login",
SceneName: "登录",
}
ma.AppendRobot(robot1)
///////////////
robot2 := lib.NewRobot(config)
robot2.ReportMap = make(map[int]map[string]*lib.Statistics)
robot2.ReportMap[1] = make(map[string]*lib.Statistics)
robot2.ReportMap[1]["user.login"] = &lib.Statistics{
ElapseTotal: 7,
CallCount: 1,
AvgElapse: 3,
MaxElapse: 5,
MinElapse: 4,
Route: "user.login",
SceneName: "登录",
}
ma.AppendRobot(robot2)
//////
robot3 := lib.NewRobot(config)
robot3.ReportMap = make(map[int]map[string]*lib.Statistics)
robot3.ReportMap[1] = make(map[string]*lib.Statistics)
robot3.ReportMap[1]["user.login"] = &lib.Statistics{
ElapseTotal: 8,
CallCount: 1,
AvgElapse: 2,
MaxElapse: 6,
MinElapse: 3,
Route: "user.login",
SceneName: "登录",
}
ma.AppendRobot(robot3)
ma.MergeResult()
robot4 := lib.NewRobot(config)
robot4.ReportMap = make(map[int]map[string]*lib.Statistics)
robot4.ReportMap[1] = make(map[string]*lib.Statistics)
robot4.ReportMap[1]["user.login"] = &lib.Statistics{
ElapseTotal: 8,
CallCount: 1,
AvgElapse: 2,
MaxElapse: 8,
MinElapse: 2,
Route: "user.login",
SceneName: "登录",
}
ma.AppendRobot(robot4)
ma.MergeResult()
fmt.Println(ma.ReportMap)
for i, v := range ma.ReportMap {
fmt.Println(i)
for j, m := range v {
fmt.Printf("【%s】 调用次数:%v 总耗时:%v 平均:%v 最大:%v 最小:%v\n", j, m.CallCount, m.ElapseTotal, m.AvgElapse, m.MaxElapse, m.MinElapse)
}
}
}

View File

@ -611,7 +611,7 @@ func (mw *MainWindow) newSceneContainer() {
//场景按钮
addSceneBtn := widget.NewButtonWithIcon("添加场景", theme.ContentAddIcon(), nil)
deleSceneBtn := widget.NewButtonWithIcon("删除场景", theme.DeleteIcon(), nil)
setNumBtn := widget.NewButtonWithIcon("设置序号", theme.ListIcon(), nil)
setBtn := widget.NewButtonWithIcon("场景配置", theme.ListIcon(), nil)
//search
searchEntry := widget.NewEntry()
@ -642,7 +642,7 @@ func (mw *MainWindow) newSceneContainer() {
if len(selectedSceneList.CachedList.Items) == 0 {
dynamic = container.NewCenter(widget.NewLabel("还没有选择任何场景"))
} else {
dynamic = container.NewBorder(container.NewHBox(setNumBtn, deleSceneBtn, layout.NewSpacer()), nil, nil, nil, selectedSceneList.ListWidget)
dynamic = container.NewBorder(container.NewHBox(setBtn, deleSceneBtn, layout.NewSpacer()), nil, nil, nil, selectedSceneList.ListWidget)
}
}
@ -650,7 +650,7 @@ func (mw *MainWindow) newSceneContainer() {
container.NewBorder(
container.NewBorder(nil, nil, container.NewHBox(addSceneBtn), nil, searchEntry), nil, nil, nil,
registerSceneList.ListWidget), dynamic)
split.Offset = 0.4
split.Offset = 0.5
mw.changeContent(split)
}
contentRender()
@ -729,8 +729,8 @@ func (mw *MainWindow) newSceneContainer() {
}
}
// 设置序号事件
setNumBtn.OnTapped = func() {
// 场景配置事件
setBtn.OnTapped = func() {
selId := selectedSceneList.SelectedId()
if selId == "" {
ShowTip("请选择一个场景")
@ -739,8 +739,12 @@ func (mw *MainWindow) newSceneContainer() {
sceneNumEntry := widget.NewEntry()
sceneNumEntry.Text = "0"
sceneLoopEntry := widget.NewEntry()
sceneLoopEntry.Text = "1"
sceneItems := []*widget.FormItem{
widget.NewFormItem("顺序号", sceneNumEntry),
widget.NewFormItem("执行次数", sceneLoopEntry),
}
// 加载
@ -752,15 +756,25 @@ func (mw *MainWindow) newSceneContainer() {
}
if sceneConf != nil {
sceneNumEntry.Text = cast.ToString(sceneConf.Num)
if sceneConf.Loop == 0 {
sceneLoopEntry.Text = "1"
} else {
sceneLoopEntry.Text = cast.ToString(sceneConf.Loop)
}
}
editSceneWin := dialog.NewForm("编辑场景序号", "确定", "取消", sceneItems, func(b bool) {
if !b {
return
}
if cast.ToInt(sceneNumEntry.Text) < 0 {
ShowTip("顺序号必须大于0")
return
}
for _, item := range mw.config.Scenes {
if item.ID == selId {
item.Num = cast.ToInt(sceneNumEntry.Text)
item.Loop = cast.ToInt32(sceneLoopEntry.Text)
}
}