#Extending existing Codec

82 messages · Page 1 of 1 (latest)

manic pagoda
#

I'm creating a new ModelFormat, and I want a Codec for it, but that codec is going to be 99% the same as the regular bbmodel codec. All I want to do is have the regular bbmodel codec, except:

  • After the regular bbmodel json is made, generate a new key-value pair in the json object which holds the custom data
  • When reading the file, first run the regular bbmodel codec, then read the data in that custom key-value pair to modify result
    This seems like something that should be relatively simple to do, just "wrapping" the regular bbmodel with some new data/operations, but I'm not sure what the best way to go about it is. Do I need to copy-paste the entire bbmodel codec and make slight changes to it?
#

Actually, could I just use the regular bbmodel codec, and add new fields to the global Project variable?

#

That seems like it maybe could work

gusty sapphire
#
// onload
property = new Property(ModelProject, "string", "free_rotation_item", {
  label: "Item ID",
  description: "The item ID of the item that the model should apply to",
  condition: { formats: [format.id] }
})

// onunload
property.delete()
#

properties are automatically saved to the bbmodel, and automatically loaded into the project

manic pagoda
#

alright, neat

gusty sapphire
#

this property can be accessed via project.free_rotation_item

manic pagoda
#

expanding on this, would it be possible to hook into wherever the exporting process is happening in order to generate a certain property?

#

the purpose of the property is for it to be parsed later by a different program

#

previously we were just parsing the bbmodel file as it is (outliner, elements, etc), but this sometimes caused issues when blockbench internals updated, and our code was relying on internal features like those that we shouldn't have

#

so basically, i just want to add a new field which has the relevant information for that other program to parse

#

the gist of it is that this field is only relevant to the external program, and isn't read by the plugin, only written to

#

so what i would really want is a way to hook into the save process, and generate this custom field with a predefined format that doesn't change over time as blockbench internals do..

#

like the idea is something like ```
function rightBeforeSaving(json) {
json.my_special_key = { ...generated by reading outliner/elements/etc... }
}

#

i dont think i need something as advanced as a property for it, since i don't really want or need to keep the data updated throughout the process, and i only care about this data being saved 1 time

#

(Property will be useful for other stuff though so thanks for telling me about it)

gusty sapphire
manic pagoda
#

alright fair

#

i guess the difficult thing is knowing when to write to the property

gusty sapphire
#

before you export

manic pagoda
#

also, this property shouldn't ever need to be read in, i dont think

gusty sapphire
#

set the property value => trigger the compile

manic pagoda
#

it's like a write only thing

gusty sapphire
#

doesnt matter, it will just get overwritten next time you export it

manic pagoda
#

yeah

#

i guess i need to figure out how to hook into the "before you export" code

gusty sapphire
#

you just add your own export action

#

that sets the property, then compiles it

#

@manic pagoda you could also do this i guess ```js
const compiled = JSON.parse(Codecs.project.compile())
compiled.my_special_key = "hello there"
const output = autoStringify(compiled)
// save output to file

#

you would just need to handle folder prompting yourself

#

if you use a property, you would just do this: ```js
project.my_special_key = "hello there"
Codecs.project.export()

#
const action = new Action("export_my_format", {
  name: "Export My Format",
  icon: "icon-here",
  condition: {
    formats: [format.id]
  },
  click() {
    project.my_special_key = "hello there"
    Codecs.project.export()
  }
})
MenuBar.addAction(action, "file.export.0")
#

that would add an action to the export menu that exports it

manic pagoda
#

i probably wouldn't want to have to click a special button to save it is the only issue with that

#

prefer to just ctrl+s and have it in the format

gusty sapphire
#

exporting works with ctrl+s, assuming that was the last thing you did

manic pagoda
#

oh, interesting

#

didnt know that

gusty sapphire
#

when you save a java block model, and ctrl+s, it saves it as json, not bbmodel, since that is the formats export

manic pagoda
#

hm

#

does the bbmodel also save?

#

or can blockbench be used to open a java block model json file

gusty sapphire
#

forget about bbmodel. think of it as "your export"

you will make a custom format, and codec. your codec will just reference the bbmodel codec. its export will do the behaviour i mentioned before

#

1 sec

manic pagoda
#

interesting, the property seems to get added to the "new project" dialog

gusty sapphire
#

you can hide it

#

theres a value you set that hides it

#

exposed

#

set exposed to false

manic pagoda
#

got it

#

okay, cool

#

so yeah i just have something like this and keep adding the rest of the functions

#

the file extension field doesn't work, probably because im deferring to the other export()

#

but that can probably be fixed fairly easily

gusty sapphire
#

1 min

#

long min

#
(() => {
  let property, originalCompile
  const id = "my_custom_format"
  const name = "Template"
  const icon = "extension"
  Plugin.register(id, {
    title: name,
    icon,
    author: "Author Name",
    description: "placeholder",
    about: "placeholder",
    tags: ["placeholder"],
    version: "1.0.0",
    min_version: "4.5.2",
    variant: "both",
    onload() {
      property = new Property(ModelProject, "string", "my_special_key", {
        label: "My Special Key"
      })
      originalCompile = Codecs.project.compile
      Codecs.project.compile = options => {
        Project.my_special_key = "hello there"
        return originalCompile.bind(Codecs.project)(options)
      }
    },
    onunload() {
      property.delete()
      Codecs.project.compile = originalCompile
    }
  })
})()

hacky one that works and works on any format

#

overwrites the bbmodel compile function with a custom one that sets the property value, then runs the original compile.

#

when uninstalling the plugin, it sets the original compile back

manic pagoda
#

thanks :>

#

however now that i know that ctrl+s can be used for the custom export, im looking into that as an option, since that seems like a better choice overall

#

it's a bit weird though since the ctrl+s for export thing isn't under this export window, it's under Save Model, but as long as there's a way im okay with it

#

the "smart save" thing seems a bit janky unfortunately, but maybe that's because im doing something weird? not sure

manic pagoda
#

I think i'm doing something wrong, but I don't know what exactly, because the feature to save multiple models just doesn't seem to be working for me

#

this is my codec, now im trying to make it so it exports 2 files, the bbmodel and also a separate file which is just the json i actually need

#

the weird thing is the behavior of the Ctrl+S and Ctrl+Alt+S keybinds / features they relate to

#

to start, i create a new project using my custom format

#

If I Ctrl+S:

  • It prompts me to save a .bbmodel file, not my custom extension
  • In the future, whenever I Ctrl+S, or even Ctrl+Alt+S, it just saves to that same .bbmodel file without prompting
    If I Ctrl+Alt+S:
  • It asks me whether to save as bbmodel, as my own type, or both
  • I pick both, and it creates and writes to both files as you'd expect
  • However, now if I do Ctrl+S or Ctrl+Alt+S, it still only ever saves the .bbmodel file, not the other one
gusty sapphire
#

¯_(ツ)_/¯

#

i would just do what i sent

manic pagoda
#

it's just frustrating since there seems to be a feature which is exactly what i'd want (exporting to multiple files, ctrl+alt+s) but it's just not working for me which I don't understand

#

thanks for all the help though i appreciate it

manic pagoda
#

found a solution, going to post in case anyone ever ends up going down this same path

#

I had to only implement compile, not export

#

the difference was that in the default implementation of export, it has this custom writer calling this.write()

#

mine was not calling this.write()

#

which was why it was breaking with the files, since Codec.write() calls afterSave(), which messes with the global variables Project.save_path and Project.export_path, which is necessary for that one feature to work

#

so yeah, either don't override export, or if you do modify export, make sure you call this.write() inside the custom_writer inside Blockbench.export

oak gulch
gusty sapphire
#

technically if you use the exact method i provided, it will only cause issues if you uninstall a plugin

#

but yeah that is better