From c37e56e4bf4f64b6b9e270f1ce559515cf414b82 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sybren=20A=2E=20St=C3=BCvel?= Date: Mon, 3 Jan 2022 18:58:14 +0100 Subject: [PATCH] =?UTF-8?q?Got=20very=E2=84=A2=20rudimentary=20job=20compi?= =?UTF-8?q?lation=20working?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- job_compilers/author.go | 46 +++++++++++++++++++ job_compilers/job_compilers.go | 23 ++++++---- .../scripts/simple_blender_render.js | 42 +++++++++++------ 3 files changed, 90 insertions(+), 21 deletions(-) create mode 100644 job_compilers/author.go diff --git a/job_compilers/author.go b/job_compilers/author.go new file mode 100644 index 00000000..195fa526 --- /dev/null +++ b/job_compilers/author.go @@ -0,0 +1,46 @@ +package job_compilers + +import ( + "github.com/dop251/goja" +) + +// Author allows scripts to author tasks and commands. +type Author struct { + runtime *goja.Runtime +} + +type AuthoredTask struct { + Name string + Commands []AuthoredCommand +} + +type AuthoredCommand struct { + Type string + Parameters map[string]string +} + +func (a *Author) Task(name string) (*AuthoredTask, error) { + at := AuthoredTask{ + name, + make([]AuthoredCommand, 0), + } + return &at, nil +} + +func (a *Author) Command(cmdType string, parameters map[string]string) (*AuthoredCommand, error) { + ac := AuthoredCommand{cmdType, parameters} + return &ac, nil +} + +func AuthorModule(r *goja.Runtime, module *goja.Object) { + a := &Author{ + runtime: r, + } + obj := module.Get("exports").(*goja.Object) + obj.Set("Task", a.Task) + obj.Set("Command", a.Command) +} + +func (at *AuthoredTask) AddCommand(ac *AuthoredCommand) { + at.Commands = append(at.Commands, *ac) +} diff --git a/job_compilers/job_compilers.go b/job_compilers/job_compilers.go index 1cf65157..7c91116c 100644 --- a/job_compilers/job_compilers.go +++ b/job_compilers/job_compilers.go @@ -2,6 +2,7 @@ package job_compilers import ( "errors" + "time" "github.com/dop251/goja" "github.com/dop251/goja_nodejs/require" @@ -40,8 +41,9 @@ func Load() (*GojaJobCompiler, error) { registry := require.NewRegistry(require.WithLoader(staticFileLoader)) registry.Enable(compiler.vm) - // NodeJS has this module both importable and globally available. + registry.RegisterNativeModule("author", AuthorModule) registry.RegisterNativeModule("process", ProcessModule) + compiler.vm.Set("author", require.Require(compiler.vm, "author")) compiler.vm.Set("process", require.Require(compiler.vm, "process")) return &compiler, nil @@ -55,10 +57,6 @@ func newGojaVM() *goja.Runtime { log.Info().Interface("args", call.Arguments).Msg("print") return goja.Undefined() }) - vm.Set("create_task", func(call goja.FunctionCall) goja.Value { - log.Info().Interface("args", call.Arguments).Msg("create_task") - return goja.Undefined() - }) vm.Set("alert", func(call goja.FunctionCall) goja.Value { log.Warn().Interface("args", call.Arguments).Msg("alert") return goja.Undefined() @@ -67,10 +65,13 @@ func newGojaVM() *goja.Runtime { } type Job struct { - ID int64 + JobID int64 Name string JobType string Priority int8 + + Created time.Time + Settings JobSettings Metadata JobMetadata } @@ -84,11 +85,17 @@ func (c *GojaJobCompiler) Run(jobType string) error { return ErrJobTypeUnknown } + created, err := time.Parse(time.RFC3339, "2022-01-03T18:53:00+01:00") + if err != nil { + panic("hard-coded timestamp is wrong") + } + job := Job{ - ID: 327, + JobID: 327, JobType: "blender-render", Priority: 50, Name: "190_0030_A.lighting", + Created: created, Settings: JobSettings{ "blender_cmd": "{blender}", "chunk_size": 5, @@ -108,7 +115,7 @@ func (c *GojaJobCompiler) Run(jobType string) error { } c.vm.Set("job", &job) - _, err := c.vm.RunProgram(program) + _, err = c.vm.RunProgram(program) return err } diff --git a/job_compilers/scripts/simple_blender_render.js b/job_compilers/scripts/simple_blender_render.js index 154baf0a..b0d5d7e5 100644 --- a/job_compilers/scripts/simple_blender_render.js +++ b/job_compilers/scripts/simple_blender_render.js @@ -2,28 +2,44 @@ var path = require('path'); print('Blender Render job submitted'); print('job: ', job) -print('running on platform', process.platform); + +const { created, settings } = job; // Determine the intermediate render output path. -function intermediate_path(render_path) { +function intermediatePath(render_path) { const basename = path.basename(render_path); - const name = `${basename}__intermediate-${job.created}`; + const name = `${basename}__intermediate-${created}`; return path.join(path.dirname(render_path), name); } +function frameChunker(frames, callback) { + callback('1-10'); + callback('11-20'); + callback('21-30'); +} // The render path contains a filename pattern, most likely '######' or // something similar. This has to be removed, so that we end up with // the directory that will contain the frames. -const render_output = path.dirname(job.settings.render_output); -print('render output', render_output); -const final_dir = path.dirname(render_output); -print('final dir ', final_dir); -const render_dir = intermediate_path(final_dir); -print('render dir ', render_dir); +const renderOutput = path.dirname(settings.render_output); +const finalDir = path.dirname(renderOutput); +const renderDir = intermediatePath(finalDir); -// for (var i = 0; i < 5; i++) { -// create_task('task' + i, 'task' + i + ' description'); -// } +let renderTasks = []; +frameChunker(settings.frames, function(chunk) { + const task = author.Task(`render-${chunk}`); + const command = author.Command('blender-render', { + cmd: settings.blender_cmd, + filepath: settings.filepath, + format: settings.format, + render_output: path.join(renderDir, path.basename(renderOutput)), + frames: chunk, + }); + task.addCommand(command); + renderTasks.push(task); +}); -print('done creating tasks'); \ No newline at end of file +print(`done creating ${renderTasks.length} tasks`); +for (const task of renderTasks) { + print(task); +} \ No newline at end of file