Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Descriptor extensions #65

Open
Anaminus opened this issue May 7, 2022 · 2 comments
Open

Descriptor extensions #65

Anaminus opened this issue May 7, 2022 · 2 comments
Labels
enhancement New feature or request

Comments

@Anaminus
Copy link
Owner

Anaminus commented May 7, 2022

  • Provides auxiliary third-party data for descriptors.
  • Extensions are isolated under $rbxmkExtensions field in the descriptor root, for forward-compatibility with Roblox's API dump format.
  • For convenience, the rbxmk API combines these extensions into their corresponding item.
  • Extra global data can be added under the $rbxmkConfig field in the descriptor root.
  • DescAction gains "Extension" field.
    • If "Element", the action applies to the corresponding item in the extensions area instead of the main area.
    • If "$rbxmkConfig", then Primary refers to a global field data via a dot-separated path. The "Value" field under Fields sets the value.

Example descriptor file:

{
	"Version": 0,
	"Classes": [],
	"Enums": [],
	"$rbxmkExtensions": {
		"Classes": {
			"Class": {
				"Fields": {
					"ExtensionKey": "ExtensionValue"
				},
				"Members": {
					"Member": {
						"Fields": {
							"ExtensionKey": "ExtensionValue"
						}
					}
				}
			}
		},
		"Enums": {
			"Enum": {
				"Fields": {
					"ExtensionKey": "ExtensionValue"
				},
				"Items": {
					"Item": {
						"Fields": {
							"ExtensionKey": "ExtensionValue"
						}
					}
				}
			}
		}
	},
	"$rbxmkConfig": {
		"Foo": {
			"Bar": [1, 2, 3]
		},
		"BrickColors": {
			"PaletteSize": 128,
			"IndexSize": 208,
			"Default": 194,
			"List": [
				{"Number":  1 , "Name": "White"         , "Color": [242, 243, 243] , "PaletteIndex":  87},
				{"Number": 21 , "Name": "Bright red"    , "Color": [196,  40,  28] , "PaletteIndex":  68},
				{"Number": 23 , "Name": "Bright blue"   , "Color": [ 13, 105, 172] , "PaletteIndex":  21},
				{"Number": 24 , "Name": "Bright yellow" , "Color": [245, 205,  48] , "PaletteIndex":  71},
				{"Number": 28 , "Name": "Dark green"    , "Color": [ 40, 127,  71] , "PaletteIndex":   8}
			]
		}
	}
}

Example patch that enhances a property with a default value:

{
	"Extend": "Element",
	"Type": 1,
	"Element": "Class",
	"Primary": "BasePart",
	"Secondary": "BrickColor",
	"Fields": {
		"Default": {
			"BrickColor": 194
		}
	}
}

Example patch that modifies global BrickColor data:

{
	"Extend": "$rbxmkConfig",
	"Type": 0,
	"Primary": "BrickColors.List.0.Color",
	"Fields": {"Value": [242, 243, 243]}
}
@Anaminus Anaminus added the enhancement New feature or request label May 7, 2022
@Anaminus
Copy link
Owner Author

Anaminus commented May 9, 2022

Descriptor extensions can be used for configuration. e.g. AttrConfig. To support this well, inheritance should have a merging strategy that enables each component to be inherited individually.

For merging the descriptor portion, the set of descriptor fields is defined as all fields that aren't $rbxmkConfig. If none of these fields are present, then the descriptor portion is considered not present, and instead inherits from the upper descriptor as usual.

The $rbxmkConfig field is merged top to bottom. That is, if a queried value does not exist on the current RootDesc, then try again with the upper RootDesc, and so on.

To block inheritance, false can be passed as before, but this will block all fields. To block just descriptor fields, a RootDesc.new() can be used. To block just config fields, RootDesc.config() can be used.

RootDesc.config

RootDesc.config(config: table): RootDesc

The config constructor returns a RootDesc with only the config fields specified by config.

@Anaminus
Copy link
Owner Author

Anaminus commented Jun 2, 2022

Handle desc extensions separately from desc format by implementing a generic json patching system.

Types:

  • JsonValue: nil|boolean|number|string|Array|Dictionary
    • Any json-compatible value.
  • JsonOperation: {op: string, from: string?, path: string, value: JsonValue?}
  • JsonPatch: {JsonOperation}
    • List of operations.

Formats:

  • The patch.json format encodes JsonPatch.
  • json format encodes JsonValue instead of union of values.

Libraries:

  • json
    • json.diff(prev: JsonValue, next: JsonValue): JsonPatch
      • Creates a patch that transforms prev into next.
    • json.patch(value: JsonValue, patch: JsonPatch): JsonValue
      • Returns copy of value transformed by patch.
    • json.string(value: JsonValue, indent: string?): string
      • Convenience alias of rbxmk.encodeFormat("json", value).
    • json.fromString(string: string): JsonValue
      • Convenience alias of rbxmk.decodeFormat("json", string).

Desc gains several members:

  • Desc.Extensions: JsonValue
    • Arbitrary json-compatable value.
  • Desc:DiffExtensions(next: JsonValue): JsonPatch
    • Creates a patch that transforms extension portion of Desc into next.
  • Desc:PatchExtensions(patch: JsonPatch)
    • Apply patch to extension portion of Desc.

Certain fields of Desc.Extensions are interpreted in certain ways:

rbxmk.globalDesc.Extensions = {
	Elements = ...,  -- Extends elements in Desc.
	Config = ...,    -- Additional non-element-specific config.
	Behaviors = ..., -- Instance behaviors.
}

Flags:

  • --desc-extend: Accepts a json formatted file that sets the extensions portion of the global Desc.
  • --desc-patch: Now requires .desc-action.json extension of given file, which is interpreted as before. Now also accepts .patch.json extension, which is interpreted as patch to extension portion of global Desc.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

1 participant