From a4f59ee62b4c4e3954ccdaac76291afa6a766096 Mon Sep 17 00:00:00 2001 From: Aaron Smith <83140718+centau@users.noreply.github.com> Date: Thu, 10 Aug 2023 15:42:58 +0100 Subject: [PATCH] Update docs --- docs/.vitepress/config.ts | 1 + docs/api/creation.md | 55 ++++++++++++++++++++++++++---- docs/api/strict-mode.md | 24 ++++++++----- docs/tut/crash-course/8-actions.md | 46 +++++++++++++++++++++++++ todo.md | 6 ++-- 5 files changed, 112 insertions(+), 20 deletions(-) create mode 100644 docs/tut/crash-course/8-actions.md diff --git a/docs/.vitepress/config.ts b/docs/.vitepress/config.ts index 1f06016..1aa4694 100644 --- a/docs/.vitepress/config.ts +++ b/docs/.vitepress/config.ts @@ -44,6 +44,7 @@ export default defineConfig({ { text: "Derived Source", link: "/tut/crash-course/5-derived-source" }, { text: "Table Source", link: "/tut/crash-course/6-table-source" }, { text: "Property Groups", link: "/tut/crash-course/7-property-groups" }, + { text: "Actions", link: "/tut/crash-course/8-actions" }, ] }, { diff --git a/docs/api/creation.md b/docs/api/creation.md index 122c1b6..838284b 100644 --- a/docs/api/creation.md +++ b/docs/api/creation.md @@ -6,7 +6,7 @@ Creates a new UI element, applying any given properties. -- ### Type +- **Type** ```lua function create(class: string): (Properties) -> Instance @@ -15,7 +15,7 @@ Creates a new UI element, applying any given properties. type Properties = Map ``` -- ### Details +- **Details** The function can take either a `string` or an `Instance` as its first argument. @@ -26,22 +26,22 @@ Creates a new UI element, applying any given properties. This returns another function that is used to apply any properties to the new instance. -- ### Property setting rules +- **Property setting rules** - If a table value is another table, that nested table is processed so that any properties inside that table are also applied to the instance just like the outer table. - If a table index is a string: - If its value is a function then it will either bind that property to - a state or connect it if the property type is a `RBXScriptSignal`. + the function or connect it if the property type is a `RBXScriptSignal`. - If the value is not a function then the property will be set to that value. - If a table index is a number: - - If its value is a function then it will parent any instances returned by - that function as children. + - If its value is a function then it will parent and bind any instances + returned by that function as children. - If its value is an instance then it will be parented to the instance. -- ### Example +- **Example** Basic element creation. @@ -77,3 +77,44 @@ Creates a new UI element, applying any given properties. } end ``` + +## action() + +Creates a callback that can be passed to `create()` to invoke custom actions on +instances. + +- **Type** + + ```lua + function action((Instance) -> (), priority: number = 1): Action + ``` + +- **Details** + + When passed to `create()`, the given callback is called with the instance + being created as the only argument. Actions take precedence over property + and child assignments. + + A priority can be optionally specified to ensure certain actions run after + other actions. Higher priority numbers are ran after lower priority numbers. + +- **Example** + + An action to listen to changed properties: + + ```lua + local function changed(property: string, callback: (new) -> ()) + return action(function(instance) + instance:GetPropertyChangedSignal("property"):Connect(function() + callback(instance[property]) + end) + end) + end + + local output = source "" + + create "TextBox" { + -- will update the `output` source anytime the text property is changed + changed("Text", output) + } + ``` diff --git a/docs/api/strict-mode.md b/docs/api/strict-mode.md index d69b527..a0f826f 100644 --- a/docs/api/strict-mode.md +++ b/docs/api/strict-mode.md @@ -1,19 +1,15 @@ # Strict Mode -Vide has a special mode called "strict mode" which is used for debugging. - -The purpose of strict mode is to help ensure stateful code is *pure* -(deterministic and free from side effects) or if there are side-effects, that -they are cleaned up correctly. - -Vide is set to strict by doing: +Strict mode is library-wide and can get set by doing: ```lua -local vide = require(path_to_vide) vide.strict = true ``` -What strict mode will do: +Strict mode is designed to help the development process by adding safety checks +and identifying improper usage. + +Currently, strict mode will: 1. Run derived sources twice a source updates. 2. Run watchers twice when a source updates. @@ -21,5 +17,15 @@ What strict mode will do: 4. Checks for `indexes()` and `values()` returning primitive values. 5. Better error reporting and stack traces. +By rerunning sources and watchers, any side-effects are made more apparent. +This also helps ensure that cleanups are being handled correctly. + +Accidental yielding within reactive scopes can break Vide's reactive graph, +which strict mode can catch. + +As well as additional safety checks, Vide will dedicate extra resources to +recording and better emitting stack traces where errors occur, particularly +when binding properties to sources. + It is recommend to develop UI with strict mode and to disable it when pushing to production. diff --git a/docs/tut/crash-course/8-actions.md b/docs/tut/crash-course/8-actions.md new file mode 100644 index 0000000..1fb2659 --- /dev/null +++ b/docs/tut/crash-course/8-actions.md @@ -0,0 +1,46 @@ +# Actions + +Actions in Vide are special callbacks that you can pass along with properties, +which will be called when those properties are being processed with the instance +being assigned to, allowing you to run custom code. + +```lua +local action = vide.action +``` + +```lua +create "TextLabel" { + Text = "test", + + action(function(instance) + print(instance.Text) + end) +} + +-- will print "test" +``` + +Actions take precedence over property and child assignment, just like property +nesting. + +Actions can be wrapped with functions to re-use specific behaviors. Below is +an example of an action used to listen for property changes: + +```lua +local function changed(property: string, callback: (new) -> ()) + return action(function(instance) + instance:GetPropertyChangedSignal(property):Connect(function() + callback(instance[property]) + end) + end) +end + +local output = source "" + +create "TextBox" { + changed("Text", output) +} +``` + +The source `output` will be updated with the new property value any time it is +changed externally. diff --git a/todo.md b/todo.md index 2cfdc63..a00dd97 100644 --- a/todo.md +++ b/todo.md @@ -5,10 +5,8 @@ - cleanup within `values()` and `indexes()` - behavior when a table source value is set to the same table - address behavior of binding property to multiples states -- strict mode - - better error reporting and stack traces - - warn when `values()` returns primitive - - warn when `values()` returns duplicate object +- better error reporting and stack traces in strict mode +- auto-enable of strict mode depending on compiler optimizaton level - implement from solid - [x] onCleanup > `cleanup()` - [x] Index > `indexes()`