github.com/alimy/mir/v4@v4.1.0/engine/engine.go (about) 1 // Copyright 2019 Michael Li <alimy@gility.net>. All rights reserved. 2 // Use of this source code is governed by Apache License 2.0 that 3 // can be found in the LICENSE file. 4 5 package engine 6 7 import ( 8 "errors" 9 "fmt" 10 "runtime" 11 "sync" 12 13 "github.com/alimy/mir/v4/core" 14 "github.com/alimy/mir/v4/internal" 15 ) 16 17 var ( 18 mu = &sync.Mutex{} 19 mirEntries = make([]any, 0, 8) 20 ) 21 22 // AddEntry add mir's entry list. 23 func AddEntry(entries ...any) { 24 mu.Lock() 25 defer mu.Unlock() 26 27 addEntries(entries...) 28 } 29 30 // Entry add mir's entry by a type 31 func Entry[T any]() { 32 mu.Lock() 33 defer mu.Unlock() 34 35 addEntries(new(T)) 36 } 37 38 // Generate generate interface code from mir's iface entry 39 func Generate(opts core.Options, entries ...any) (err error) { 40 mu.Lock() 41 defer mu.Unlock() 42 43 addEntries(entries...) 44 if len(mirEntries) == 0 { 45 return errors.New("mir entries is empty maybe need add entries first") 46 } 47 48 initOpts := core.InitFrom(opts) 49 p := core.ParserByName(initOpts.ParserName) 50 // use default parser when not set parser name from options 51 if p == nil { 52 p = core.DefaultParser() 53 } 54 if err = p.Init(initOpts.ParserOpts()); err != nil { 55 return 56 } 57 58 g := core.GeneratorByName(initOpts.GeneratorName) 59 if g == nil { 60 return fmt.Errorf("unknow or yet not supported generator that name of %s", initOpts.GeneratorName) 61 } 62 if err = g.Init(initOpts.GeneratorOpts()); err != nil { 63 return 64 } 65 66 core.Logus("run in %s", initOpts.RunMode) 67 switch initOpts.RunMode { 68 case core.InSerialDebugMode, core.InSerialMode: 69 err = doInSerial(p, g, mirEntries) 70 case core.InConcurrentDebugMode, core.InConcurrentMode: 71 err = doInConcurrent(p, g, mirEntries) 72 } 73 return err 74 } 75 76 func addEntries(entries ...any) { 77 mirEntries = append(mirEntries, entries...) 78 } 79 80 func doInSerial(p core.Parser, g core.Generator, entries []any) error { 81 descriptors, err := p.Parse(entries) 82 if err == nil { 83 return g.Generate(descriptors) 84 } 85 return err 86 } 87 88 func doInConcurrent(p core.Parser, g core.Generator, entries []any) error { 89 numCPU := runtime.NumCPU() 90 runtime.GOMAXPROCS(numCPU) 91 core.Logus("set GOMAXPROCS: %d", numCPU) 92 93 ctx := internal.NewMirCtx(16) 94 95 go p.ParseContext(ctx, entries) 96 go g.GenerateContext(ctx) 97 98 return ctx.Wait() 99 }