diff --git a/.gitignore b/.gitignore index adf8f72..356d112 100644 --- a/.gitignore +++ b/.gitignore @@ -20,4 +20,4 @@ # Go workspace file go.work - +go.sum diff --git a/GManager.go b/GManager.go new file mode 100644 index 0000000..4fa2b2d --- /dev/null +++ b/GManager.go @@ -0,0 +1,85 @@ +package main + +import ( + "sync" +) + +type GManager struct { + sync.WaitGroup + tlock sync.RWMutex + tasks map[string]*GTask +} + +const ( + GMSG_EXIT string = "GManager.Exit" +) + +func (my *GManager) Init() *GManager { + my.tasks = make(map[string]*GTask) + return my +} + +func (my *GManager) RegistTask(task *GTask, name string) { + my.tlock.Lock() + defer my.tlock.Unlock() + my.tasks[name] = task +} + +func (my *GManager) CreateTask(name string, qsize int) *GTask { + t := new(GTask).Init(my, qsize) + t.GManager = my + my.RegistTask(t, name) + + return t +} + +func (my *GManager) Enter() { + my.WaitGroup.Add(1) +} + +func (my *GManager) Exit() { + my.WaitGroup.Done() +} + +func (my *GManager) Join() { + my.WaitGroup.Wait() +} + +func (my *GManager) Broadcast(event interface{}) { + my.tlock.RLock() + defer my.tlock.RUnlock() + // Last to first. + for name := range my.tasks { + t := my.tasks[name] + t.EnQueueSync(event) + } +} + +func (my *GManager) BroadcastWithout(event interface{}, without string) { + my.tlock.RLock() + defer my.tlock.RUnlock() + // Last to first. + for name := range my.tasks { + if without == name { + continue + } + t := my.tasks[name] + t.EnQueueSync(event) + } +} + +func (my *GManager) ReqExit() { + my.Broadcast(GMSG_EXIT) +} + +func (my *GManager) ReqTaskExit(name string) { + t, f := my.tasks[name] + if f { + t.EnQueueSync(GMSG_EXIT) + } +} + +func (my *GManager) GetQueue(name string) (GQueue, bool) { + t, f := my.tasks[name] + return t.GQueue, f +} diff --git a/GQueue.go b/GQueue.go new file mode 100644 index 0000000..adbb3ea --- /dev/null +++ b/GQueue.go @@ -0,0 +1,45 @@ +package main + +import ( + "errors" + "time" +) + +type GQueue chan interface{} + +const ( + ERR_GQUEUE_TIMEOUT string = "gqueue timeout" +) + +func (my *GQueue) Init(size int) *GQueue { + *my = make(chan interface{}, size) + return my +} + +func (my *GQueue) EnQueueSync(itm interface{}) { + *my <- itm +} + +func (my *GQueue) EnQueue(itm interface{}, timeout time.Duration) error { + select { + case *my <- itm: + return nil + case <-time.After(timeout): + return errors.New(ERR_GQUEUE_TIMEOUT) + } +} + +func (my *GQueue) DeQueueSync() interface{} { + itm := <-*my + return itm +} + +func (my *GQueue) DeQueue(timeout time.Duration) (interface{}, error) { + var itm interface{} + select { + case itm = <-*my: + return itm, nil + case <-time.After(timeout): + return nil, errors.New(ERR_GQUEUE_TIMEOUT) + } +} diff --git a/GTask.go b/GTask.go new file mode 100644 index 0000000..f2cae88 --- /dev/null +++ b/GTask.go @@ -0,0 +1,35 @@ +package main + +import ( + "sync" +) + +type GTask struct { + GQueue + sync.WaitGroup + *GManager +} + +func (my *GTask) Init(manager *GManager, qsize int) *GTask { + my.GManager = manager + my.GQueue.Init(qsize) + return my +} + +func (my *GTask) Enter() { + if my.GManager != nil { + my.GManager.Enter() + } + my.WaitGroup.Add(1) +} + +func (my *GTask) Exit() { + my.WaitGroup.Done() + if my.GManager != nil { + my.GManager.Exit() + } +} + +func (my *GTask) Join() { + my.WaitGroup.Wait() +} diff --git a/Log.go b/Log.go new file mode 100644 index 0000000..c1ca4e7 --- /dev/null +++ b/Log.go @@ -0,0 +1,78 @@ +package main + +import "blacktea.vip.cpolar.top/OrgGo/simplelog" + +type Loger struct { + *simplelog.SimpleLog +} + +type EULogType int + +const ( + LevelTrace EULogLevel = simplelog.LevelTrace + LevelDebug EULogLevel = simplelog.LevelDebug + LevelInfo EULogLevel = simplelog.LevelInfo + LevelWarn EULogLevel = simplelog.LevelWarn + LevelError EULogLevel = simplelog.LevelError + LevelFatal EULogLevel = simplelog.LevelFatal +) + +type EULogLevel int + +func (my *Loger) Init(file string, LogLevel EULogLevel) *Loger { + switch file { + case "": + my.SimpleLog = new(simplelog.SimpleLog).InitStd(int(LogLevel), simplelog.Ltime|simplelog.Lfile|simplelog.Llevel) + default: + my.SimpleLog = new(simplelog.SimpleLog).InitRotating(file, 1024*1000, 10, int(LogLevel)) + } + return my +} + +func (my *Loger) Trace(v ...interface{}) { + my.SimpleLog.Output(2, simplelog.LevelTrace, "", v...) +} + +func (my *Loger) Debug(v ...interface{}) { + my.SimpleLog.Output(2, simplelog.LevelDebug, "", v...) +} + +func (my *Loger) Info(v ...interface{}) { + my.SimpleLog.Output(2, simplelog.LevelInfo, "", v...) +} + +func (my *Loger) Warn(v ...interface{}) { + my.SimpleLog.Output(2, simplelog.LevelWarn, "", v...) +} + +func (my *Loger) Error(v ...interface{}) { + my.SimpleLog.Output(2, simplelog.LevelError, "", v...) +} + +func (my *Loger) Fatal(v ...interface{}) { + my.SimpleLog.Output(2, simplelog.LevelFatal, "", v...) +} + +func (my *Loger) Tracef(format string, v ...interface{}) { + my.SimpleLog.Output(2, simplelog.LevelTrace, format, v...) +} + +func (my *Loger) Debugf(format string, v ...interface{}) { + my.SimpleLog.Output(2, simplelog.LevelDebug, format, v...) +} + +func (my *Loger) Infof(format string, v ...interface{}) { + my.SimpleLog.Output(2, simplelog.LevelInfo, format, v...) +} + +func (my *Loger) Warnf(format string, v ...interface{}) { + my.SimpleLog.Output(2, simplelog.LevelWarn, format, v...) +} + +func (my *Loger) Errorf(format string, v ...interface{}) { + my.SimpleLog.Output(2, simplelog.LevelError, format, v...) +} + +func (my *Loger) Fatalf(format string, v ...interface{}) { + my.SimpleLog.Output(2, simplelog.LevelFatal, format, v...) +} diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..96dc049 --- /dev/null +++ b/go.mod @@ -0,0 +1,40 @@ +module BlackForest + +go 1.22.3 + +require ( + blacktea.vip.cpolar.top/OrgGo/simplelog v1.0.5 + fyne.io/fyne/v2 v2.5.0 +) + +require ( + fyne.io/systray v1.11.0 // indirect + github.com/BurntSushi/toml v1.4.0 // indirect + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/fredbi/uri v1.1.0 // indirect + github.com/fsnotify/fsnotify v1.7.0 // indirect + github.com/fyne-io/gl-js v0.0.0-20220119005834-d2da28d9ccfe // indirect + github.com/fyne-io/glfw-js v0.0.0-20240101223322-6e1efdc71b7a // indirect + github.com/fyne-io/image v0.0.0-20220602074514-4956b0afb3d2 // indirect + github.com/go-gl/gl v0.0.0-20211210172815-726fda9656d6 // indirect + github.com/go-gl/glfw/v3.3/glfw v0.0.0-20240506104042-037f3cc74f2a // indirect + github.com/go-text/render v0.1.0 // indirect + github.com/go-text/typesetting v0.1.0 // indirect + github.com/godbus/dbus/v5 v5.1.0 // indirect + github.com/gopherjs/gopherjs v1.17.2 // indirect + github.com/jeandeaual/go-locale v0.0.0-20240223122105-ce5225dcaa49 // indirect + github.com/jsummers/gobmp v0.0.0-20151104160322-e2ba15ffa76e // indirect + github.com/nicksnyder/go-i18n/v2 v2.4.0 // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/rymdport/portal v0.2.2 // indirect + github.com/srwiley/oksvg v0.0.0-20221011165216-be6e8873101c // indirect + github.com/srwiley/rasterx v0.0.0-20220730225603-2ab79fcdd4ef // indirect + github.com/stretchr/testify v1.8.4 // indirect + github.com/yuin/goldmark v1.7.1 // indirect + golang.org/x/image v0.18.0 // indirect + golang.org/x/mobile v0.0.0-20231127183840-76ac6878050a // indirect + golang.org/x/net v0.25.0 // indirect + golang.org/x/sys v0.20.0 // indirect + golang.org/x/text v0.16.0 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect +) diff --git a/main.go b/main.go new file mode 100644 index 0000000..6d296ad --- /dev/null +++ b/main.go @@ -0,0 +1,24 @@ +package main + +import ( + "fyne.io/fyne/v2" + "fyne.io/fyne/v2/app" +) + +type MGCore struct { + *GManager + *Loger + + fyne.App + MainWin fyne.Window +} + +var Core MGCore + +func main() { + Core.App = app.New() + Core.MainWin = Core.App.NewWindow("Black Forest") + Core.MainWin.Resize(fyne.NewSize(800, 600)) + + Core.MainWin.ShowAndRun() +}