mirror of
https://github.com/go-gst/go-gst.git
synced 2025-09-26 20:11:18 +08:00
187 lines
4.5 KiB
Go
187 lines
4.5 KiB
Go
package main
|
|
|
|
import (
|
|
"bufio"
|
|
"io"
|
|
"os"
|
|
"path"
|
|
"path/filepath"
|
|
"reflect"
|
|
"strings"
|
|
"text/template"
|
|
)
|
|
|
|
func main() {
|
|
var wd string
|
|
var err error
|
|
if len(os.Args) == 1 {
|
|
wd, err = os.Getwd()
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
} else {
|
|
wd = os.Args[1]
|
|
}
|
|
|
|
cfg := buildCfgFromDir(wd)
|
|
|
|
outfile := path.Join(wd, "zzgenerated_plugin.go")
|
|
out, err := os.Create(outfile)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
defer out.Close()
|
|
|
|
pluginTmpl.Execute(out, map[string]interface{}{
|
|
"Config": cfg,
|
|
})
|
|
}
|
|
|
|
type libraryConfig struct {
|
|
Plugin *pluginConfig
|
|
Element *elementConfig
|
|
}
|
|
|
|
type pluginConfig struct {
|
|
Name, Description, Version, License, Source, Package, Origin, ReleaseDate string
|
|
}
|
|
|
|
type elementConfig struct {
|
|
Name, Rank, Impl, Subclass, Interfaces string
|
|
}
|
|
|
|
func buildCfgFromDir(dir string) *libraryConfig {
|
|
cfg := &libraryConfig{
|
|
Plugin: &pluginConfig{},
|
|
Element: &elementConfig{},
|
|
}
|
|
err := filepath.Walk(dir, func(path string, info os.FileInfo, err error) error {
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if info.IsDir() {
|
|
return nil
|
|
}
|
|
if !strings.HasSuffix(path, ".go") {
|
|
return nil
|
|
}
|
|
parseFileIntoCfg(path, cfg)
|
|
return nil
|
|
})
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
return cfg
|
|
}
|
|
|
|
func parseFileIntoCfg(path string, cfg *libraryConfig) {
|
|
f, err := os.Open(path)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
scanner := bufio.NewScanner(f)
|
|
for scanner.Scan() {
|
|
line := scanner.Text()
|
|
if !strings.HasPrefix(line, "// +") {
|
|
continue
|
|
}
|
|
line = strings.TrimPrefix(line, "// +")
|
|
if strings.HasPrefix(line, "plugin:") {
|
|
parseLineToConfig("plugin", line, cfg.Plugin)
|
|
continue
|
|
}
|
|
if strings.HasPrefix(line, "element:") {
|
|
parseLineToConfig("element", line, cfg.Element)
|
|
}
|
|
}
|
|
if err := scanner.Err(); err != nil && err != io.EOF {
|
|
panic(err)
|
|
}
|
|
}
|
|
|
|
func parseLineToConfig(prefix, line string, cfg interface{}) {
|
|
trimmed := strings.TrimPrefix(line, prefix+":")
|
|
arg, val := parseArgAndValue(trimmed)
|
|
v := reflect.ValueOf(cfg).Elem()
|
|
for i := 0; i < v.NumField(); i++ {
|
|
if v.Type().Field(i).Name == arg {
|
|
v.FieldByName(arg).SetString(val)
|
|
}
|
|
}
|
|
}
|
|
|
|
func parseArgAndValue(line string) (arg, val string) {
|
|
spl := strings.Split(line, "=")
|
|
return spl[0], spl[1]
|
|
}
|
|
|
|
var pluginTmpl = template.Must(template.New("").Funcs(template.FuncMap{
|
|
"adjustedName": func(name string) string {
|
|
return strings.ToLower(strings.Replace(name, "-", "_", -1))
|
|
},
|
|
"splitInterfaces": func(ifacesString string) []string {
|
|
return strings.Split(ifacesString, ",")
|
|
},
|
|
"extendsFromBase": func(subclass string) bool {
|
|
if strings.HasPrefix(subclass, "base.") {
|
|
return true
|
|
}
|
|
return false
|
|
},
|
|
}).Parse(`// !WARNING! THIS FILE WAS GENERATED BY GST-PLUGIN-GEN !WARNING! //
|
|
package main
|
|
|
|
import "C"
|
|
|
|
import (
|
|
"unsafe"
|
|
|
|
"github.com/go-gst/go-gst/gst"
|
|
{{- if (.Config.Element.Subclass | extendsFromBase) }}
|
|
"github.com/go-gst/go-gst/gst/base"
|
|
{{- end }}
|
|
)
|
|
|
|
// The metadata for this plugin
|
|
var pluginMeta = &gst.PluginMetadata{
|
|
MajorVersion: gst.VersionMajor,
|
|
MinorVersion: gst.VersionMinor,
|
|
Name: "{{ .Config.Plugin.Name }}",
|
|
Description: "{{ .Config.Plugin.Description }}",
|
|
Version: "{{ .Config.Plugin.Version }}",
|
|
License: {{ .Config.Plugin.License }},
|
|
Source: "{{ .Config.Plugin.Source }}",
|
|
Package: "{{ .Config.Plugin.Package }}",
|
|
Origin: "{{ .Config.Plugin.Origin }}",
|
|
ReleaseDate: "{{ .Config.Plugin.ReleaseDate }}",
|
|
// The init function is called to register elements provided by the plugin.
|
|
Init: func(plugin *gst.Plugin) bool {
|
|
return gst.RegisterElement(
|
|
plugin,
|
|
// The name of the element
|
|
"{{ .Config.Element.Name }}",
|
|
// The rank of the element
|
|
{{ .Config.Element.Rank }},
|
|
// The GoElement implementation for the element
|
|
&{{ .Config.Element.Impl }}{},
|
|
// The base subclass this element extends
|
|
{{ .Config.Element.Subclass }},
|
|
{{- if .Config.Element.Interfaces }}
|
|
// The interfaces this element implements
|
|
{{- range $index, $interface := .Config.Element.Interfaces | splitInterfaces }}
|
|
{{ $interface }},
|
|
{{- end }}
|
|
{{- end }}
|
|
)
|
|
},
|
|
}
|
|
|
|
// A single method must be exported from the compiled library that provides for GStreamer
|
|
// to fetch the description and init function for this plugin. The name of the method
|
|
// must match the format gst_plugin_NAME_get_desc, where NAME is the name of the compiled
|
|
// artifact with or without the "libgst" prefix and hyphens are replaced with underscores.
|
|
|
|
//export gst_plugin_{{ .Config.Plugin.Name | adjustedName }}_get_desc
|
|
func gst_plugin_{{ .Config.Plugin.Name | adjustedName }}_get_desc() unsafe.Pointer { return pluginMeta.Export() }
|
|
`))
|