{
    "componentChunkName": "component---src-components-page-template-jsx",
    "path": "/system/foundations/nuclear",
    "result": {"data":{"mdx":{"id":"ceeef6dc-5870-5eb3-b6ad-615ce40c63ba","body":"var _excluded = [\"components\"];\n\nfunction _extends() { _extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nfunction _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }\n\nfunction _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }\n\n/* @jsxRuntime classic */\n\n/* @jsx mdx */\nvar _frontmatter = {\n  \"section\": \"System\",\n  \"chapter\": \"Foundations\",\n  \"title\": \"NUClear\",\n  \"description\": \"Introduction to NUClear and how it is used in the NUbots codebase.\",\n  \"slug\": \"/system/foundations/nuclear\",\n  \"authors\": [\"Ysobel Sims (@ysims)\", \"Cameron Murtagh (@CMurtagh-LGTM)\"]\n};\nvar layoutProps = {\n  _frontmatter: _frontmatter\n};\nvar MDXLayout = \"wrapper\";\nreturn function MDXContent(_ref) {\n  var components = _ref.components,\n      props = _objectWithoutProperties(_ref, _excluded);\n\n  return mdx(MDXLayout, _extends({}, layoutProps, props, {\n    components: components,\n    mdxType: \"MDXLayout\"\n  }), mdx(\"p\", null, \"NUClear is the software framework used in the main NUbots codebase. It is a message passing system designed to be modular and fast.\"), mdx(\"p\", null, \"This page is intended to be a practical summary of the official \", mdx(\"a\", {\n    parentName: \"p\",\n    \"href\": \"https://nuclear.readthedocs.io/en/latest/\"\n  }, \"NUClear documentation\"), \", which contains a detailed description of NUClear. The \", mdx(\"a\", {\n    parentName: \"p\",\n    \"href\": \"https://github.com/Fastcode/NUClearRoles\"\n  }, \"NUClear Roles repository\"), \" contains a detailed description of the NUClear roles system, much of which the \", mdx(\"a\", {\n    parentName: \"p\",\n    \"href\": \"#nuclear-roles\"\n  }, \"roles section\"), \" in this page is based off.\"), mdx(\"h2\", {\n    \"id\": \"components\",\n    \"style\": {\n      \"position\": \"relative\"\n    }\n  }, mdx(\"a\", {\n    parentName: \"h2\",\n    \"href\": \"#components\",\n    \"aria-label\": \"components permalink\",\n    \"className\": \"anchor before\"\n  }, mdx(\"svg\", {\n    parentName: \"a\",\n    \"aria-hidden\": \"true\",\n    \"focusable\": \"false\",\n    \"height\": \"16\",\n    \"version\": \"1.1\",\n    \"viewBox\": \"0 0 16 16\",\n    \"width\": \"16\"\n  }, mdx(\"path\", {\n    parentName: \"svg\",\n    \"fillRule\": \"evenodd\",\n    \"d\": \"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"\n  }))), \"Components\"), mdx(\"h3\", {\n    \"id\": \"powerplant\",\n    \"style\": {\n      \"position\": \"relative\"\n    }\n  }, mdx(\"a\", {\n    parentName: \"h3\",\n    \"href\": \"#powerplant\",\n    \"aria-label\": \"powerplant permalink\",\n    \"className\": \"anchor before\"\n  }, mdx(\"svg\", {\n    parentName: \"a\",\n    \"aria-hidden\": \"true\",\n    \"focusable\": \"false\",\n    \"height\": \"16\",\n    \"version\": \"1.1\",\n    \"viewBox\": \"0 0 16 16\",\n    \"width\": \"16\"\n  }, mdx(\"path\", {\n    parentName: \"svg\",\n    \"fillRule\": \"evenodd\",\n    \"d\": \"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"\n  }))), \"PowerPlant\"), mdx(\"img\", {\n    \"src\": \"/de297389021f4ee716d7d780a1b9c8c1/power_plant.svg\",\n    \"alt\": \"A collection of Reactors around the PowerPlant in the center. Double ended arrows point to and from the PowerPlant to each Reactor.\",\n    \"title\": \"PowerPlant with Reactors. Image: https://nuclear.readthedocs.io/en/latest/components.html\"\n  }), mdx(\"p\", null, \"The PowerPlant is the central message system through which reactors communicate. It takes ownership of any data emitted by reactors into the system and executes the required reactions. NUClear is \", mdx(\"a\", {\n    parentName: \"p\",\n    \"href\": \"https://en.wikipedia.org/wiki/Multithreading_(computer_architecture)\"\n  }, \"multi-threaded\"), \". The PowerPlant handles all threading logic.\"), mdx(\"h3\", {\n    \"id\": \"reactors\",\n    \"style\": {\n      \"position\": \"relative\"\n    }\n  }, mdx(\"a\", {\n    parentName: \"h3\",\n    \"href\": \"#reactors\",\n    \"aria-label\": \"reactors permalink\",\n    \"className\": \"anchor before\"\n  }, mdx(\"svg\", {\n    parentName: \"a\",\n    \"aria-hidden\": \"true\",\n    \"focusable\": \"false\",\n    \"height\": \"16\",\n    \"version\": \"1.1\",\n    \"viewBox\": \"0 0 16 16\",\n    \"width\": \"16\"\n  }, mdx(\"path\", {\n    parentName: \"svg\",\n    \"fillRule\": \"evenodd\",\n    \"d\": \"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"\n  }))), \"Reactors\"), mdx(\"p\", null, \"A reactor can be thought of as a module. All modules in the NUClear system are an extension of \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"NUClear::Reactor\"), \". Reactors define reactions and the conditions under which they will process. They may also emit data to the PowerPlant.\"), mdx(\"h3\", {\n    \"id\": \"reactions-and-tasks\",\n    \"style\": {\n      \"position\": \"relative\"\n    }\n  }, mdx(\"a\", {\n    parentName: \"h3\",\n    \"href\": \"#reactions-and-tasks\",\n    \"aria-label\": \"reactions and tasks permalink\",\n    \"className\": \"anchor before\"\n  }, mdx(\"svg\", {\n    parentName: \"a\",\n    \"aria-hidden\": \"true\",\n    \"focusable\": \"false\",\n    \"height\": \"16\",\n    \"version\": \"1.1\",\n    \"viewBox\": \"0 0 16 16\",\n    \"width\": \"16\"\n  }, mdx(\"path\", {\n    parentName: \"svg\",\n    \"fillRule\": \"evenodd\",\n    \"d\": \"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"\n  }))), \"Reactions and Tasks\"), mdx(\"p\", null, \"Reactions run tasks when the required data is available and/or when certain conditions are true. A task is the current execution of a defined reaction within the system. These functions are bound by NUClear as callbacks, and it is the execution of these callbacks which will assign tasks to a thread.\"), mdx(\"p\", null, \"Reactions are created by subscribing to the PowerPlant through \", mdx(\"a\", {\n    parentName: \"p\",\n    \"href\": \"#on-statements\"\n  }, \"DSL On Statements\"), \".\"), mdx(\"h2\", {\n    \"id\": \"nuclear-dsl\",\n    \"style\": {\n      \"position\": \"relative\"\n    }\n  }, mdx(\"a\", {\n    parentName: \"h2\",\n    \"href\": \"#nuclear-dsl\",\n    \"aria-label\": \"nuclear dsl permalink\",\n    \"className\": \"anchor before\"\n  }, mdx(\"svg\", {\n    parentName: \"a\",\n    \"aria-hidden\": \"true\",\n    \"focusable\": \"false\",\n    \"height\": \"16\",\n    \"version\": \"1.1\",\n    \"viewBox\": \"0 0 16 16\",\n    \"width\": \"16\"\n  }, mdx(\"path\", {\n    parentName: \"svg\",\n    \"fillRule\": \"evenodd\",\n    \"d\": \"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"\n  }))), \"NUClear DSL\"), mdx(\"h3\", {\n    \"id\": \"on-statements\",\n    \"style\": {\n      \"position\": \"relative\"\n    }\n  }, mdx(\"a\", {\n    parentName: \"h3\",\n    \"href\": \"#on-statements\",\n    \"aria-label\": \"on statements permalink\",\n    \"className\": \"anchor before\"\n  }, mdx(\"svg\", {\n    parentName: \"a\",\n    \"aria-hidden\": \"true\",\n    \"focusable\": \"false\",\n    \"height\": \"16\",\n    \"version\": \"1.1\",\n    \"viewBox\": \"0 0 16 16\",\n    \"width\": \"16\"\n  }, mdx(\"path\", {\n    parentName: \"svg\",\n    \"fillRule\": \"evenodd\",\n    \"d\": \"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"\n  }))), \"On Statements\"), mdx(\"p\", null, \"Reactors make subscriptions to the PowerPlant using on statements, which define the conditions for reactions to run.\"), mdx(\"p\", null, \"An on statement has the following form\"), mdx(\"pre\", null, mdx(\"code\", {\n    parentName: \"pre\",\n    \"className\": \"language-cpp\"\n  }, \"on<...>(...).then(...);\\n\")), mdx(\"p\", null, \"This can be split into three parts. The first is the \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"on<...>\"), \" which is the DSL request. The \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"(...)\"), \" contains any runtime arguments. \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \".then(...);\"), \" is the callback, which is what will be executed when the reaction is triggered.\"), mdx(\"h4\", {\n    \"id\": \"dsl-request\",\n    \"style\": {\n      \"position\": \"relative\"\n    }\n  }, mdx(\"a\", {\n    parentName: \"h4\",\n    \"href\": \"#dsl-request\",\n    \"aria-label\": \"dsl request permalink\",\n    \"className\": \"anchor before\"\n  }, mdx(\"svg\", {\n    parentName: \"a\",\n    \"aria-hidden\": \"true\",\n    \"focusable\": \"false\",\n    \"height\": \"16\",\n    \"version\": \"1.1\",\n    \"viewBox\": \"0 0 16 16\",\n    \"width\": \"16\"\n  }, mdx(\"path\", {\n    parentName: \"svg\",\n    \"fillRule\": \"evenodd\",\n    \"d\": \"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"\n  }))), \"DSL Request\"), mdx(\"p\", null, \"The DSL request is \\\"fused\\\" together by combining any number of DSL words. The combination of these words will define the kind of reaction which is being requested. For example, \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"Trigger\"), \" will define a reaction that should occur when a required data type is emitted, while \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"Every\"), \" will define periodic reactions.\"), mdx(\"p\", null, \"For reactions to occur, at least one Binding DSL word should be present in the DSL Request. The binding DSL words are: \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"Trigger\"), \", \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"With\"), \", \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"Every\"), \", \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"Always\"), \", \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"Startup\"), \", \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"Shutdown\"), \", \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"TCP\"), \", \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"UDP\"), \", and \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"Network\"), \".\"), mdx(\"table\", null, mdx(\"thead\", {\n    parentName: \"table\"\n  }, mdx(\"tr\", {\n    parentName: \"thead\"\n  }, mdx(\"th\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, \"DSL Word\"), mdx(\"th\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, \"Description\"))), mdx(\"tbody\", {\n    parentName: \"table\"\n  }, mdx(\"tr\", {\n    parentName: \"tbody\"\n  }, mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, \"Trigger\"), mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, \"Is used to request data dependent reactions. \", mdx(\"inlineCode\", {\n    parentName: \"td\"\n  }, \"on<Trigger<T>>()\"), \" will execute the task whenever T is emitted into the system. Read only access to T is given via a callback. \", mdx(\"inlineCode\", {\n    parentName: \"td\"\n  }, \"on<Trigger<T1, T2, ... >>()\"), \" requires multiple types and will only trigger when all the trigger types have been emitted at least once since the last occurrence of the event.\")), mdx(\"tr\", {\n    parentName: \"tbody\"\n  }, mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, \"With\"), mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, \"Is used to define any extra data which should be provided to a subscribing reaction. This should be fused with at least one other DSL word as the use of this word alone will not trigger a reaction within the system. \", mdx(\"inlineCode\", {\n    parentName: \"td\"\n  }, \"on<Trigger<T1>, With<T2>>()\"), \" will trigger when T1 is emitted into the system. It will give read-only access of T1 and T2 to the callback. If T2 is not present when T1 is emitted to the system, the reaction will not run.\")), mdx(\"tr\", {\n    parentName: \"tbody\"\n  }, mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, \"Last\"), mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, \"Instructs the PowerPlant to store the last \", mdx(\"span\", {\n    parentName: \"td\",\n    \"className\": \"math math-inline\"\n  }, mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"katex\"\n  }, mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"katex-mathml\"\n  }, mdx(\"math\", {\n    parentName: \"span\",\n    \"xmlns\": \"http://www.w3.org/1998/Math/MathML\"\n  }, mdx(\"semantics\", {\n    parentName: \"math\"\n  }, mdx(\"mrow\", {\n    parentName: \"semantics\"\n  }, mdx(\"mi\", {\n    parentName: \"mrow\"\n  }, \"n\")), mdx(\"annotation\", {\n    parentName: \"semantics\",\n    \"encoding\": \"application/x-tex\"\n  }, \"n\")))), mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"katex-html\",\n    \"aria-hidden\": \"true\"\n  }, mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"base\"\n  }, mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"strut\",\n    \"style\": {\n      \"height\": \"0.4306em\"\n    }\n  }), mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mord mathnormal\"\n  }, \"n\"))))), \" messages received (of the associated type) to the cache and provide read-only access to the subscribing reaction. \", mdx(\"inlineCode\", {\n    parentName: \"td\"\n  }, \"on<Last<n, Trigger<T, ...>>>()\"), \" will store the next \", mdx(\"span\", {\n    parentName: \"td\",\n    \"className\": \"math math-inline\"\n  }, mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"katex\"\n  }, mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"katex-mathml\"\n  }, mdx(\"math\", {\n    parentName: \"span\",\n    \"xmlns\": \"http://www.w3.org/1998/Math/MathML\"\n  }, mdx(\"semantics\", {\n    parentName: \"math\"\n  }, mdx(\"mrow\", {\n    parentName: \"semantics\"\n  }, mdx(\"mi\", {\n    parentName: \"mrow\"\n  }, \"n\")), mdx(\"annotation\", {\n    parentName: \"semantics\",\n    \"encoding\": \"application/x-tex\"\n  }, \"n\")))), mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"katex-html\",\n    \"aria-hidden\": \"true\"\n  }, mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"base\"\n  }, mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"strut\",\n    \"style\": {\n      \"height\": \"0.4306em\"\n    }\n  }), mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mord mathnormal\"\n  }, \"n\"))))), \" messages of each of the \", mdx(\"inlineCode\", {\n    parentName: \"td\"\n  }, \"Trigger\"), \" types in a list with the oldest message first. After \", mdx(\"span\", {\n    parentName: \"td\",\n    \"className\": \"math math-inline\"\n  }, mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"katex\"\n  }, mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"katex-mathml\"\n  }, mdx(\"math\", {\n    parentName: \"span\",\n    \"xmlns\": \"http://www.w3.org/1998/Math/MathML\"\n  }, mdx(\"semantics\", {\n    parentName: \"math\"\n  }, mdx(\"mrow\", {\n    parentName: \"semantics\"\n  }, mdx(\"mi\", {\n    parentName: \"mrow\"\n  }, \"n\")), mdx(\"annotation\", {\n    parentName: \"semantics\",\n    \"encoding\": \"application/x-tex\"\n  }, \"n\")))), mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"katex-html\",\n    \"aria-hidden\": \"true\"\n  }, mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"base\"\n  }, mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"strut\",\n    \"style\": {\n      \"height\": \"0.4306em\"\n    }\n  }), mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mord mathnormal\"\n  }, \"n\"))))), \" messages are stored, the trigger of a new reaction will cause the oldest message to be dropped and the newest copy appended to the list.\")), mdx(\"tr\", {\n    parentName: \"tbody\"\n  }, mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, \"Optional\"), mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, \"Is used to signify any optional properties in the DSL request. \", mdx(\"inlineCode\", {\n    parentName: \"td\"\n  }, \"on<Trigger<T1>, Optional<With<T2>>>()\"), \" will run when T1 is emitted into the system. If T2 is available, then the reaction will be given read-only access to the most recent emission of T2. If it is not available, it will give the callback a \", mdx(\"inlineCode\", {\n    parentName: \"td\"\n  }, \"nullptr\"), \".\")), mdx(\"tr\", {\n    parentName: \"tbody\"\n  }, mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, \"Single\"), mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, \"Is used to specify that only one instance of the associated reaction can execute at any given point during runtime. \", mdx(\"inlineCode\", {\n    parentName: \"td\"\n  }, \"on<Trigger<T, ...>, Single>()\"), \" will only allow one task for this reaction to be executed or in the queue at any given time. This should be fused with another DSL word, such as \", mdx(\"inlineCode\", {\n    parentName: \"td\"\n  }, \"Trigger\"), \" in the example. This word is equivalent to \", mdx(\"inlineCode\", {\n    parentName: \"td\"\n  }, \"Buffer<1>\"), \".\")), mdx(\"tr\", {\n    parentName: \"tbody\"\n  }, mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, \"Buffer\"), mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, \"Is used to specify that up to \", mdx(\"span\", {\n    parentName: \"td\",\n    \"className\": \"math math-inline\"\n  }, mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"katex\"\n  }, mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"katex-mathml\"\n  }, mdx(\"math\", {\n    parentName: \"span\",\n    \"xmlns\": \"http://www.w3.org/1998/Math/MathML\"\n  }, mdx(\"semantics\", {\n    parentName: \"math\"\n  }, mdx(\"mrow\", {\n    parentName: \"semantics\"\n  }, mdx(\"mi\", {\n    parentName: \"mrow\"\n  }, \"n\")), mdx(\"annotation\", {\n    parentName: \"semantics\",\n    \"encoding\": \"application/x-tex\"\n  }, \"n\")))), mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"katex-html\",\n    \"aria-hidden\": \"true\"\n  }, mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"base\"\n  }, mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"strut\",\n    \"style\": {\n      \"height\": \"0.4306em\"\n    }\n  }), mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mord mathnormal\"\n  }, \"n\"))))), \" instances of the associated reaction can execute during runtime. \", mdx(\"inlineCode\", {\n    parentName: \"td\"\n  }, \"on<Trigger<T, ...>, Buffer<n>>>()\"), \" will create and schedule a new task if there are less than \", mdx(\"span\", {\n    parentName: \"td\",\n    \"className\": \"math math-inline\"\n  }, mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"katex\"\n  }, mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"katex-mathml\"\n  }, mdx(\"math\", {\n    parentName: \"span\",\n    \"xmlns\": \"http://www.w3.org/1998/Math/MathML\"\n  }, mdx(\"semantics\", {\n    parentName: \"math\"\n  }, mdx(\"mrow\", {\n    parentName: \"semantics\"\n  }, mdx(\"mi\", {\n    parentName: \"mrow\"\n  }, \"n\")), mdx(\"annotation\", {\n    parentName: \"semantics\",\n    \"encoding\": \"application/x-tex\"\n  }, \"n\")))), mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"katex-html\",\n    \"aria-hidden\": \"true\"\n  }, mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"base\"\n  }, mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"strut\",\n    \"style\": {\n      \"height\": \"0.4306em\"\n    }\n  }), mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"mord mathnormal\"\n  }, \"n\"))))), \" existing tasks for this reaction. This should be fused with another DSL word, such as \", mdx(\"inlineCode\", {\n    parentName: \"td\"\n  }, \"Trigger\"), \" in the example. \", mdx(\"inlineCode\", {\n    parentName: \"td\"\n  }, \"Buffer<1>\"), \" is equivalent to \", mdx(\"inlineCode\", {\n    parentName: \"td\"\n  }, \"Single\"), \".\")), mdx(\"tr\", {\n    parentName: \"tbody\"\n  }, mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, \"Priority\"), mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, \"Assigns a priority to any tasks created to determine scheduling order in the PowerPlant. \", mdx(\"inlineCode\", {\n    parentName: \"td\"\n  }, \"on<Trigger<T, ...>, Priority::HIGH>()\"), \" will schedule the task with \", mdx(\"inlineCode\", {\n    parentName: \"td\"\n  }, \"HIGH\"), \" priority when the reaction is triggered. Available priority settings are \", mdx(\"inlineCode\", {\n    parentName: \"td\"\n  }, \"REALTIME\"), \", \", mdx(\"inlineCode\", {\n    parentName: \"td\"\n  }, \"HIGH\"), \", \", mdx(\"inlineCode\", {\n    parentName: \"td\"\n  }, \"NORMAL\"), \", \", mdx(\"inlineCode\", {\n    parentName: \"td\"\n  }, \"LOW\"), \", and \", mdx(\"inlineCode\", {\n    parentName: \"td\"\n  }, \"IDLE\"), \". This should be fused with another DSL word, such as \", mdx(\"inlineCode\", {\n    parentName: \"td\"\n  }, \"Trigger\"), \" in the example.\")), mdx(\"tr\", {\n    parentName: \"tbody\"\n  }, mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, \"Sync\"), mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, \"Sets the synchronisation for a group of tasks. \", mdx(\"inlineCode\", {\n    parentName: \"td\"\n  }, \"on<Trigger<T, ...>, Sync<Group>>()\"), \" will allow only one task from \", mdx(\"inlineCode\", {\n    parentName: \"td\"\n  }, \"Group\"), \" to execute at any given time. Tasks will be queued if there is already a task from this \", mdx(\"inlineCode\", {\n    parentName: \"td\"\n  }, \"Group\"), \" running. This word helps prevent race conditions. This should be fused with another DSL word, such as \", mdx(\"inlineCode\", {\n    parentName: \"td\"\n  }, \"Trigger\"), \" in the example.\")), mdx(\"tr\", {\n    parentName: \"tbody\"\n  }, mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, \"Every\"), mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, \"Used to request periodic reactions in the system. \", mdx(\"inlineCode\", {\n    parentName: \"td\"\n  }, \"on<Every<2, std::chrono::seconds>()\"), \" will create a task every two seconds. \", mdx(\"inlineCode\", {\n    parentName: \"td\"\n  }, \"on<Every<2, Per<std::chrono::seconds>>()\"), \" will create a task two times per second.\")), mdx(\"tr\", {\n    parentName: \"tbody\"\n  }, mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, \"Always\"), mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, \"Used to request continuous reactions in the system. \", mdx(\"inlineCode\", {\n    parentName: \"td\"\n  }, \"on<Always>\"), \" will ensure a single instance of the associated reaction is running at all times. \", mdx(\"inlineCode\", {\n    parentName: \"td\"\n  }, \"Always\"), \" runs in its own thread rather than using the thread pool.\")), mdx(\"tr\", {\n    parentName: \"tbody\"\n  }, mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, \"Startup\"), mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, \"Used to specify reactions which should occur at startup. \", mdx(\"inlineCode\", {\n    parentName: \"td\"\n  }, \"on<Startup>()\"), \" will create a task after all reactors have been installed into the PowerPlant but before the system starts the main execution phase.\")), mdx(\"tr\", {\n    parentName: \"tbody\"\n  }, mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, \"Shutdown\"), mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, \"Used to specify any reactions/tasks which should occur during shutdown. \", mdx(\"inlineCode\", {\n    parentName: \"td\"\n  }, \"on<Shutdown>()\"), \" will create a task after the shutdown command has been emitted and all existing tasks have completed.\")), mdx(\"tr\", {\n    parentName: \"tbody\"\n  }, mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, \"IO\"), mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, \"Used to trigger reactions based on standard I/O operations using file descriptors. \", mdx(\"inlineCode\", {\n    parentName: \"td\"\n  }, \"on<IO>(pipe/stream/comms, io_status)\"), \" will create a task when the communication line matches the given status. For example, \", mdx(\"inlineCode\", {\n    parentName: \"td\"\n  }, \"on<IO>(my_file_descriptor, IO::READ)\"), \" will create the task when the given file descriptor has data available to read.\")), mdx(\"tr\", {\n    parentName: \"tbody\"\n  }, mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, \"Network\"), mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, \"NUClear provides a networking protocol to send messages to other devices on the network. \", mdx(\"inlineCode\", {\n    parentName: \"td\"\n  }, \"on<Network<T>>()\"), \" will create a task when T is emitted using the emission type \", mdx(\"inlineCode\", {\n    parentName: \"td\"\n  }, \"Scope::NETWORK\"), \".\")), mdx(\"tr\", {\n    parentName: \"tbody\"\n  }, mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, \"Configuration\"), mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, \"Used to set configuration values. File name is a runtime argument. Is of the form \", mdx(\"inlineCode\", {\n    parentName: \"td\"\n  }, \"on<Configuration>(\\\"Config.yaml\\\").then(...)\"), \". The runtime argument can also be a folder to enable monitoring for all changes in that folder.\")))), mdx(\"p\", null, \"More information on DSL words for on statements can be found in the \", mdx(\"a\", {\n    parentName: \"p\",\n    \"href\": \"https://nuclear.readthedocs.io/en/latest/dsl.html#on-statements\"\n  }, \"NUClear documentation\"), \".\"), mdx(\"h4\", {\n    \"id\": \"runtime-arguments\",\n    \"style\": {\n      \"position\": \"relative\"\n    }\n  }, mdx(\"a\", {\n    parentName: \"h4\",\n    \"href\": \"#runtime-arguments\",\n    \"aria-label\": \"runtime arguments permalink\",\n    \"className\": \"anchor before\"\n  }, mdx(\"svg\", {\n    parentName: \"a\",\n    \"aria-hidden\": \"true\",\n    \"focusable\": \"false\",\n    \"height\": \"16\",\n    \"version\": \"1.1\",\n    \"viewBox\": \"0 0 16 16\",\n    \"width\": \"16\"\n  }, mdx(\"path\", {\n    parentName: \"svg\",\n    \"fillRule\": \"evenodd\",\n    \"d\": \"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"\n  }))), \"Runtime arguments\"), mdx(\"p\", null, \"Some DSL words will provide the ability to make changes to the system during runtime. This means that NUClear avoids the need for a system restart should a configuration, port number, or file need to be changed while the system is running.\"), mdx(\"p\", null, \"The DSL words that take runtime arguments are: \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"IO\"), \", \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"TCP\"), \", \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"UDP\"), \" and \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"Configuration\"), \".\"), mdx(\"h4\", {\n    \"id\": \"callback\",\n    \"style\": {\n      \"position\": \"relative\"\n    }\n  }, mdx(\"a\", {\n    parentName: \"h4\",\n    \"href\": \"#callback\",\n    \"aria-label\": \"callback permalink\",\n    \"className\": \"anchor before\"\n  }, mdx(\"svg\", {\n    parentName: \"a\",\n    \"aria-hidden\": \"true\",\n    \"focusable\": \"false\",\n    \"height\": \"16\",\n    \"version\": \"1.1\",\n    \"viewBox\": \"0 0 16 16\",\n    \"width\": \"16\"\n  }, mdx(\"path\", {\n    parentName: \"svg\",\n    \"fillRule\": \"evenodd\",\n    \"d\": \"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"\n  }))), \"Callback\"), mdx(\"p\", null, \"The callback which will execute when the reaction is triggered during runtime can be defined using a C++ lambda function. These are of the form\"), mdx(\"pre\", null, mdx(\"code\", {\n    parentName: \"pre\",\n    \"className\": \"language-cpp\"\n  }, \"[this](args...){\\n    statements...\\n}\\n\")), mdx(\"p\", null, \"The \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"args\"), \" will generally be based off the conditions for the reaction, such as access to data. For example:\"), mdx(\"pre\", null, mdx(\"code\", {\n    parentName: \"pre\"\n  }, \"on<Trigger<dataType>>().then([this](const dataType& value) {\\n    // Do things\\n});\\n\")), mdx(\"p\", null, \"Capturing the \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"this\"), \" pointer will allow your reaction to access other members of your \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"Reactor\"), \" (e.g. configuration data).\"), mdx(\"h3\", {\n    \"id\": \"emit-statements\",\n    \"style\": {\n      \"position\": \"relative\"\n    }\n  }, mdx(\"a\", {\n    parentName: \"h3\",\n    \"href\": \"#emit-statements\",\n    \"aria-label\": \"emit statements permalink\",\n    \"className\": \"anchor before\"\n  }, mdx(\"svg\", {\n    parentName: \"a\",\n    \"aria-hidden\": \"true\",\n    \"focusable\": \"false\",\n    \"height\": \"16\",\n    \"version\": \"1.1\",\n    \"viewBox\": \"0 0 16 16\",\n    \"width\": \"16\"\n  }, mdx(\"path\", {\n    parentName: \"svg\",\n    \"fillRule\": \"evenodd\",\n    \"d\": \"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"\n  }))), \"Emit Statements\"), mdx(\"p\", null, \"Emit statements are used by Reactors wanting to emit data to the PowerPlant. When using NUClear, data will most likely be emitted during a reaction. However, where necessary, emissions can also occur during reactor construction, or in some cases from within the PowerPlant itself.\"), mdx(\"p\", null, \"Any data emitted to the PowerPlant will be sent with a unique pointer. The PowerPlant will take ownership of this pointer and run any necessary callbacks to trigger reactions.\"), mdx(\"p\", null, \"Data can be emitted under varying scopes. These can be local or network emissions. More information can be found on emit statements in the \", mdx(\"a\", {\n    parentName: \"p\",\n    \"href\": \"https://nuclear.readthedocs.io/en/latest/dsl.html#emit-statements\"\n  }, \"NUClear documentation\"), \".\"), mdx(\"h4\", {\n    \"id\": \"local-emissions\",\n    \"style\": {\n      \"position\": \"relative\"\n    }\n  }, mdx(\"a\", {\n    parentName: \"h4\",\n    \"href\": \"#local-emissions\",\n    \"aria-label\": \"local emissions permalink\",\n    \"className\": \"anchor before\"\n  }, mdx(\"svg\", {\n    parentName: \"a\",\n    \"aria-hidden\": \"true\",\n    \"focusable\": \"false\",\n    \"height\": \"16\",\n    \"version\": \"1.1\",\n    \"viewBox\": \"0 0 16 16\",\n    \"width\": \"16\"\n  }, mdx(\"path\", {\n    parentName: \"svg\",\n    \"fillRule\": \"evenodd\",\n    \"d\": \"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"\n  }))), \"Local Emissions\"), mdx(\"p\", null, \"Local emissions send data to the local instance of the NUClear PowerPlant. Essentially this is the current running process. There are a number of scopes under which these emissions can take place. The syntax for these emissions are \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"emit<Scope::SCOPE>(data, args...);\"), \", where \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"SCOPE\"), \" is replaced with a scope as defined below.\"), mdx(\"table\", null, mdx(\"thead\", {\n    parentName: \"table\"\n  }, mdx(\"tr\", {\n    parentName: \"thead\"\n  }, mdx(\"th\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, \"Scope\"), mdx(\"th\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, \"Description\"))), mdx(\"tbody\", {\n    parentName: \"table\"\n  }, mdx(\"tr\", {\n    parentName: \"tbody\"\n  }, mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, \"LOCAL\"), mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, \"When emitting data under this scope, tasks are distributed via the thread pool for execution. This is the default behaviour when emitting.\")), mdx(\"tr\", {\n    parentName: \"tbody\"\n  }, mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, \"DIRECT\"), mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, \"When emitting data under this scope, the tasks created as a result of this emission will bypass the threadpool, and be executed immediately.\")), mdx(\"tr\", {\n    parentName: \"tbody\"\n  }, mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, \"INITIALISE\"), mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, \"This scope emits data as the system starts up.\")), mdx(\"tr\", {\n    parentName: \"tbody\"\n  }, mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, \"DELAY\"), mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, \"This will emit data, after the provided delay. The syntax includes a delay time \", mdx(\"inlineCode\", {\n    parentName: \"td\"\n  }, \"emit<Scope::DELAY>(data, delay(ticks));\"), \".\")))), mdx(\"h4\", {\n    \"id\": \"network-emitting\",\n    \"style\": {\n      \"position\": \"relative\"\n    }\n  }, mdx(\"a\", {\n    parentName: \"h4\",\n    \"href\": \"#network-emitting\",\n    \"aria-label\": \"network emitting permalink\",\n    \"className\": \"anchor before\"\n  }, mdx(\"svg\", {\n    parentName: \"a\",\n    \"aria-hidden\": \"true\",\n    \"focusable\": \"false\",\n    \"height\": \"16\",\n    \"version\": \"1.1\",\n    \"viewBox\": \"0 0 16 16\",\n    \"width\": \"16\"\n  }, mdx(\"path\", {\n    parentName: \"svg\",\n    \"fillRule\": \"evenodd\",\n    \"d\": \"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"\n  }))), \"Network Emitting\"), mdx(\"p\", null, \"Network emissions can be used to send data through the network on which the current system is running.\"), mdx(\"table\", null, mdx(\"thead\", {\n    parentName: \"table\"\n  }, mdx(\"tr\", {\n    parentName: \"thead\"\n  }, mdx(\"th\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, \"Scope\"), mdx(\"th\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, \"Description\"))), mdx(\"tbody\", {\n    parentName: \"table\"\n  }, mdx(\"tr\", {\n    parentName: \"tbody\"\n  }, mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, \"UDP\"), mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, \"Emits data as a UDP packet over the network. Is of the form \", mdx(\"inlineCode\", {\n    parentName: \"td\"\n  }, \"emit<Scope::UDP>(data, to_addr, to_port);\"), \".\")), mdx(\"tr\", {\n    parentName: \"tbody\"\n  }, mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, \"NETWORK\"), mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, \"Emits data over the network to other NUClear environments. Is of the form \", mdx(\"inlineCode\", {\n    parentName: \"td\"\n  }, \"emit<Scope::NETWORK>(data, target, reliable);\"), \". The \", mdx(\"inlineCode\", {\n    parentName: \"td\"\n  }, \"reliable\"), \" flag, if \", mdx(\"inlineCode\", {\n    parentName: \"td\"\n  }, \"true\"), \", will cause NUClear to continue sending the \", mdx(\"inlineCode\", {\n    parentName: \"td\"\n  }, \"data\"), \" until it receives an \", mdx(\"inlineCode\", {\n    parentName: \"td\"\n  }, \"ACK\"), \"nowledgement from the \", mdx(\"inlineCode\", {\n    parentName: \"td\"\n  }, \"target\"), \".\")))), mdx(\"h2\", {\n    \"id\": \"managing-reactions\",\n    \"style\": {\n      \"position\": \"relative\"\n    }\n  }, mdx(\"a\", {\n    parentName: \"h2\",\n    \"href\": \"#managing-reactions\",\n    \"aria-label\": \"managing reactions permalink\",\n    \"className\": \"anchor before\"\n  }, mdx(\"svg\", {\n    parentName: \"a\",\n    \"aria-hidden\": \"true\",\n    \"focusable\": \"false\",\n    \"height\": \"16\",\n    \"version\": \"1.1\",\n    \"viewBox\": \"0 0 16 16\",\n    \"width\": \"16\"\n  }, mdx(\"path\", {\n    parentName: \"svg\",\n    \"fillRule\": \"evenodd\",\n    \"d\": \"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"\n  }))), \"Managing Reactions\"), mdx(\"p\", null, \"During system runtime, executing reactions can be managed via their associated reaction handles. A reaction handle is provided for binding \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"on\"), \" statements. Once an \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"on\"), \" statement has been bound, the reaction handle will be \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"enabled\"), \". If necessary, reactions can toggle between \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"enabled\"), \" and \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"disabled\"), \" during runtime.\"), mdx(\"table\", null, mdx(\"thead\", {\n    parentName: \"table\"\n  }, mdx(\"tr\", {\n    parentName: \"thead\"\n  }, mdx(\"th\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, \"Handle\"), mdx(\"th\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, \"Description\"))), mdx(\"tbody\", {\n    parentName: \"table\"\n  }, mdx(\"tr\", {\n    parentName: \"tbody\"\n  }, mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, \"disable()\"), mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, \"Disables the reaction. Tasks will not be created if triggered.\")), mdx(\"tr\", {\n    parentName: \"tbody\"\n  }, mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, \"enable()\"), mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, \"Enables the reaction so that associated tasks will be scheduled and queued when the reaction is triggered.\")), mdx(\"tr\", {\n    parentName: \"tbody\"\n  }, mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, \"enable(bool set)\"), mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, \"Sets the run status of the reaction handle. \", mdx(\"inlineCode\", {\n    parentName: \"td\"\n  }, \"true\"), \" will enable the reaction and \", mdx(\"inlineCode\", {\n    parentName: \"td\"\n  }, \"false\"), \" will disable it.\")), mdx(\"tr\", {\n    parentName: \"tbody\"\n  }, mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, \"enabled()\"), mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, \"Determines the current status of the reaction. Returns \", mdx(\"inlineCode\", {\n    parentName: \"td\"\n  }, \"true\"), \" if the reaction is enabled, and \", mdx(\"inlineCode\", {\n    parentName: \"td\"\n  }, \"false\"), \" otherwise.\")), mdx(\"tr\", {\n    parentName: \"tbody\"\n  }, mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, \"unbind()\"), mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, \"Removes a reaction request from the runtime environment. This action is not reversible, once a reaction has been unbound, it is no longer available for further use during that runtime.\")))), mdx(\"h2\", {\n    \"id\": \"nuclear-roles\",\n    \"style\": {\n      \"position\": \"relative\"\n    }\n  }, mdx(\"a\", {\n    parentName: \"h2\",\n    \"href\": \"#nuclear-roles\",\n    \"aria-label\": \"nuclear roles permalink\",\n    \"className\": \"anchor before\"\n  }, mdx(\"svg\", {\n    parentName: \"a\",\n    \"aria-hidden\": \"true\",\n    \"focusable\": \"false\",\n    \"height\": \"16\",\n    \"version\": \"1.1\",\n    \"viewBox\": \"0 0 16 16\",\n    \"width\": \"16\"\n  }, mdx(\"path\", {\n    parentName: \"svg\",\n    \"fillRule\": \"evenodd\",\n    \"d\": \"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"\n  }))), \"NUClear Roles\"), mdx(\"p\", null, \"The NUClear Roles system is a build and messaging system for the NUClear framework. It uses \", mdx(\"a\", {\n    parentName: \"p\",\n    \"href\": \"https://cmake.org/\"\n  }, \"CMake\"), \" and \", mdx(\"a\", {\n    parentName: \"p\",\n    \"href\": \"https://www.python.org/\"\n  }, \"Python\"), \" to manage the construction of various executables made up of a selection of modules. These executables are called roles.\"), mdx(\"p\", null, \"CMake is used as the main system for generating the libraries and executables that are used for the final binary. Note that it utilises \", mdx(\"a\", {\n    parentName: \"p\",\n    \"href\": \"https://en.wikipedia.org/wiki/Glob_(programming)\"\n  }, \"globbing\"), \" to find the sources that are used for modules. If you add or remove a file, you must rerun CMake to locate the new files.\"), mdx(\"h3\", {\n    \"id\": \"directories\",\n    \"style\": {\n      \"position\": \"relative\"\n    }\n  }, mdx(\"a\", {\n    parentName: \"h3\",\n    \"href\": \"#directories\",\n    \"aria-label\": \"directories permalink\",\n    \"className\": \"anchor before\"\n  }, mdx(\"svg\", {\n    parentName: \"a\",\n    \"aria-hidden\": \"true\",\n    \"focusable\": \"false\",\n    \"height\": \"16\",\n    \"version\": \"1.1\",\n    \"viewBox\": \"0 0 16 16\",\n    \"width\": \"16\"\n  }, mdx(\"path\", {\n    parentName: \"svg\",\n    \"fillRule\": \"evenodd\",\n    \"d\": \"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"\n  }))), \"Directories\"), mdx(\"p\", null, \"There are six main directories in the NUClear Roles system and can be seen in the main NUbots codebase.\"), mdx(\"table\", null, mdx(\"thead\", {\n    parentName: \"table\"\n  }, mdx(\"tr\", {\n    parentName: \"thead\"\n  }, mdx(\"th\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, \"Directory\"), mdx(\"th\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, \"Description\"))), mdx(\"tbody\", {\n    parentName: \"table\"\n  }, mdx(\"tr\", {\n    parentName: \"tbody\"\n  }, mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, mdx(\"inlineCode\", {\n    parentName: \"td\"\n  }, \"module\")), mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, \"contains the NUClear reactors. Is broken into the various subsystems. These are \", mdx(\"inlineCode\", {\n    parentName: \"td\"\n  }, \"behaviour\"), \", \", mdx(\"inlineCode\", {\n    parentName: \"td\"\n  }, \"extension\"), \", \", mdx(\"inlineCode\", {\n    parentName: \"td\"\n  }, \"input\"), \", \", mdx(\"inlineCode\", {\n    parentName: \"td\"\n  }, \"localisation\"), \", \", mdx(\"inlineCode\", {\n    parentName: \"td\"\n  }, \"motion\"), \", \", mdx(\"inlineCode\", {\n    parentName: \"td\"\n  }, \"output\"), \", \", mdx(\"inlineCode\", {\n    parentName: \"td\"\n  }, \"platform\"), \", \", mdx(\"inlineCode\", {\n    parentName: \"td\"\n  }, \"support\"), \", \", mdx(\"inlineCode\", {\n    parentName: \"td\"\n  }, \"tools\"), \" and \", mdx(\"inlineCode\", {\n    parentName: \"td\"\n  }, \"vision\"), \".\")), mdx(\"tr\", {\n    parentName: \"tbody\"\n  }, mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, mdx(\"inlineCode\", {\n    parentName: \"td\"\n  }, \"message\")), mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, \"contains the message types for the system. The \", mdx(\"inlineCode\", {\n    parentName: \"td\"\n  }, \"message\"), \" folder is located in the \", mdx(\"inlineCode\", {\n    parentName: \"td\"\n  }, \"shared\"), \" directory. This is broken into the various subsystems much like the \", mdx(\"inlineCode\", {\n    parentName: \"td\"\n  }, \"module\"), \" directory.\")), mdx(\"tr\", {\n    parentName: \"tbody\"\n  }, mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, mdx(\"inlineCode\", {\n    parentName: \"td\"\n  }, \"extension\")), mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, \"contains any NUClear DSL extensions, such as \", mdx(\"inlineCode\", {\n    parentName: \"td\"\n  }, \"Configuration\"), \". This is located in the \", mdx(\"inlineCode\", {\n    parentName: \"td\"\n  }, \"shared\"), \" directory.\")), mdx(\"tr\", {\n    parentName: \"tbody\"\n  }, mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, mdx(\"inlineCode\", {\n    parentName: \"td\"\n  }, \"utility\")), mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, \"contains utility code that is shared amongst NUClear Reactors, such as Kinematics and Mathematics utilities. This is located in the \", mdx(\"inlineCode\", {\n    parentName: \"td\"\n  }, \"shared\"), \" directory.\")), mdx(\"tr\", {\n    parentName: \"tbody\"\n  }, mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, mdx(\"inlineCode\", {\n    parentName: \"td\"\n  }, \"roles\")), mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, \"contains all the NUClear role files.\")), mdx(\"tr\", {\n    parentName: \"tbody\"\n  }, mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, mdx(\"inlineCode\", {\n    parentName: \"td\"\n  }, \"tools\")), mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, \"contains any command line extensions for the \", mdx(\"inlineCode\", {\n    parentName: \"td\"\n  }, \"b\"), \" script, such as \", mdx(\"inlineCode\", {\n    parentName: \"td\"\n  }, \"build\"), \" and \", mdx(\"inlineCode\", {\n    parentName: \"td\"\n  }, \"configure\"), \".\")))), mdx(\"h3\", {\n    \"id\": \"roles\",\n    \"style\": {\n      \"position\": \"relative\"\n    }\n  }, mdx(\"a\", {\n    parentName: \"h3\",\n    \"href\": \"#roles\",\n    \"aria-label\": \"roles permalink\",\n    \"className\": \"anchor before\"\n  }, mdx(\"svg\", {\n    parentName: \"a\",\n    \"aria-hidden\": \"true\",\n    \"focusable\": \"false\",\n    \"height\": \"16\",\n    \"version\": \"1.1\",\n    \"viewBox\": \"0 0 16 16\",\n    \"width\": \"16\"\n  }, mdx(\"path\", {\n    parentName: \"svg\",\n    \"fillRule\": \"evenodd\",\n    \"d\": \"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"\n  }))), \"Roles\"), mdx(\"p\", null, \"Roles are executables containing a specified list of modules. They are called \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"<executablename>.role\"), \", where \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"<executablename>\"), \" is the name of the final binary that will be created.\"), mdx(\"p\", null, \"The name of each module is described as a fully qualified C++ class without the initial \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"module\"), \" namespace. These modules will then be installed in order when the executable is run. This is important to note as it means modules that have dependencies on other modules may want to be lower in the list. For example installing log handler modules should happen before installing other modules so their output can be seen. It will use this name to locate the module so the directory structure must match the name. An example of a role file would be:\"), mdx(\"pre\", null, mdx(\"code\", {\n    parentName: \"pre\",\n    \"className\": \"language-cpp\"\n  }, \"NUCLEAR_ROLE(\\n    # Some global modules that are useful\\n    extension::FileWatcher\\n    support::logging::ConsoleLogHandler\\n\\n    # Input from USB3 Cameras\\n    input::Camera\\n)\\n\")), mdx(\"p\", null, \"This role file would create an executable with the modules \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"module::extension::FileWatcher\"), \", \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"module::support::logging::ConsoleLogHandler\"), \" and \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"module::input::Camera\"), \". This file is a CMake file so you are able to use # to declare comments.\"), mdx(\"h3\", {\n    \"id\": \"nbs-files\",\n    \"style\": {\n      \"position\": \"relative\"\n    }\n  }, mdx(\"a\", {\n    parentName: \"h3\",\n    \"href\": \"#nbs-files\",\n    \"aria-label\": \"nbs files permalink\",\n    \"className\": \"anchor before\"\n  }, mdx(\"svg\", {\n    parentName: \"a\",\n    \"aria-hidden\": \"true\",\n    \"focusable\": \"false\",\n    \"height\": \"16\",\n    \"version\": \"1.1\",\n    \"viewBox\": \"0 0 16 16\",\n    \"width\": \"16\"\n  }, mdx(\"path\", {\n    parentName: \"svg\",\n    \"fillRule\": \"evenodd\",\n    \"d\": \"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"\n  }))), \"NBS Files\"), mdx(\"p\", null, \"NBS files are NUClear Binary Stream files. To make it easier to serialise streams of messages for storage sharing and playback, NUClear Roles defines a format for serialising messages to files. This format is based on the Neutron messaging system and NUClear's networking protocol. An \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"nbs\"), \" file has the following frames repeated continuously:\"), mdx(\"table\", null, mdx(\"thead\", {\n    parentName: \"table\"\n  }, mdx(\"tr\", {\n    parentName: \"thead\"\n  }, mdx(\"th\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, \"Name\"), mdx(\"th\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, \"Type\"), mdx(\"th\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, \"Description\"))), mdx(\"tbody\", {\n    parentName: \"table\"\n  }, mdx(\"tr\", {\n    parentName: \"tbody\"\n  }, mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, \"header\"), mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, \"char\", \"[3]\"), mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, \"the header sequence 0xE2, 0x98, 0xA2 (the radioactive symbol \\u2622 in UTF-8)\")), mdx(\"tr\", {\n    parentName: \"tbody\"\n  }, mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, \"size\"), mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, \"uint32\"), mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, \"the size of the frame after this byte in bytes\")), mdx(\"tr\", {\n    parentName: \"tbody\"\n  }, mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, \"timestamp\"), mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, \"uint64\"), mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, \"the timestamp of this frame in microseconds. Does not have to be a UTC timestamp.\")), mdx(\"tr\", {\n    parentName: \"tbody\"\n  }, mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, \"hash\"), mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, \"uint64\"), mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, \"a 64 bit hash that identifies the type of the message\")), mdx(\"tr\", {\n    parentName: \"tbody\"\n  }, mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, \"payload\"), mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, \"char\", \"*\"), mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, \"the serialised payload bytes\")))), mdx(\"p\", null, \"All values within this format are little endian.\"), mdx(\"p\", null, \"An \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \".nbz\"), \" or \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \".nbs.gz\"), \" file is a compressed \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"nbs\"), \" file using gzip.\"), mdx(\"p\", null, \"NBS files can have an associated index file. This allows for quicker random access to the coresponding nbs file. An \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \".nbs.idx\"), \" file has the following frames, each compressed with gzip, repeated continuously:\"), mdx(\"table\", null, mdx(\"thead\", {\n    parentName: \"table\"\n  }, mdx(\"tr\", {\n    parentName: \"thead\"\n  }, mdx(\"th\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, \"Name\"), mdx(\"th\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, \"Type\"), mdx(\"th\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, \"Description\"))), mdx(\"tbody\", {\n    parentName: \"table\"\n  }, mdx(\"tr\", {\n    parentName: \"tbody\"\n  }, mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, \"hash\"), mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, \"uint64\"), mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, \"The 64-bit xxhash for the payload type\")), mdx(\"tr\", {\n    parentName: \"tbody\"\n  }, mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, \"subtype\"), mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, \"uint32\"), mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, \"The \", mdx(\"inlineCode\", {\n    parentName: \"td\"\n  }, \"id\"), \" of the message if it exists, otherwise 0\")), mdx(\"tr\", {\n    parentName: \"tbody\"\n  }, mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, \"timestamp\"), mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, \"uint64\"), mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, \"The \", mdx(\"inlineCode\", {\n    parentName: \"td\"\n  }, \"timestamp\"), \" field of the message if it exists or the timestamp at which it was emitted in nanoseconds\")), mdx(\"tr\", {\n    parentName: \"tbody\"\n  }, mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, \"offset\"), mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, \"uint64\"), mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, \"Offset to start of the coresponding nbs frame, i.e. to just before the radiation symbol \\u2622\")), mdx(\"tr\", {\n    parentName: \"tbody\"\n  }, mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, \"size\"), mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, \"uint32\"), mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": null\n  }, \"Size of the whole packet from the radiation symbol\")))), mdx(\"p\", null, \"All values within the index file are little endian.\"), mdx(\"h3\", {\n    \"id\": \"neutrons\",\n    \"style\": {\n      \"position\": \"relative\"\n    }\n  }, mdx(\"a\", {\n    parentName: \"h3\",\n    \"href\": \"#neutrons\",\n    \"aria-label\": \"neutrons permalink\",\n    \"className\": \"anchor before\"\n  }, mdx(\"svg\", {\n    parentName: \"a\",\n    \"aria-hidden\": \"true\",\n    \"focusable\": \"false\",\n    \"height\": \"16\",\n    \"version\": \"1.1\",\n    \"viewBox\": \"0 0 16 16\",\n    \"width\": \"16\"\n  }, mdx(\"path\", {\n    parentName: \"svg\",\n    \"fillRule\": \"evenodd\",\n    \"d\": \"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"\n  }))), \"Neutrons\"), mdx(\"p\", null, \"Reactors emit data in the form of messages called Neutrons. Neutrons are \", mdx(\"a\", {\n    parentName: \"p\",\n    \"href\": \"https://developers.google.com/protocol-buffers\"\n  }, \"Protobuf\"), \" messages in a C++ wrapper. These are all located in the \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"shared/message/\"), \" directory, and have the \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \".proto\"), \" extension. An example is \", mdx(\"a\", {\n    parentName: \"p\",\n    \"href\": \"https://github.com/NUbots/NUbots/blob/105b78ad6655801f5f74d029cbd169ba8e8cb5e8/shared/message/motion/WalkCommand.proto\"\n  }, mdx(\"inlineCode\", {\n    parentName: \"a\"\n  }, \"WalkCommand.proto\")), \":\"), mdx(\"pre\", null, mdx(\"code\", {\n    parentName: \"pre\",\n    \"className\": \"language-cpp\"\n  }, \"syntax = \\\"proto3\\\";\\n\\npackage message.motion;\\n\\nimport \\\"Vector.proto\\\";\\n\\nmessage WalkCommand {\\n    uint64 subsumptionId = 1;  // reservation identifier for servo control\\n    vec3   command       = 2;  // x and y are velocity in m/s and angle is in rads/s\\n}\\n\")), mdx(\"h2\", {\n    \"id\": \"examples\",\n    \"style\": {\n      \"position\": \"relative\"\n    }\n  }, mdx(\"a\", {\n    parentName: \"h2\",\n    \"href\": \"#examples\",\n    \"aria-label\": \"examples permalink\",\n    \"className\": \"anchor before\"\n  }, mdx(\"svg\", {\n    parentName: \"a\",\n    \"aria-hidden\": \"true\",\n    \"focusable\": \"false\",\n    \"height\": \"16\",\n    \"version\": \"1.1\",\n    \"viewBox\": \"0 0 16 16\",\n    \"width\": \"16\"\n  }, mdx(\"path\", {\n    parentName: \"svg\",\n    \"fillRule\": \"evenodd\",\n    \"d\": \"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"\n  }))), \"Examples\"), mdx(\"p\", null, \"These examples use links to specific commits in the NUbots GitHub repository. They are likely out of date and don't reflect the functionality in the current main branch. They are intended to be used as examples to help understand the NUClear framework.\"), mdx(\"h3\", {\n    \"id\": \"on-statements-1\",\n    \"style\": {\n      \"position\": \"relative\"\n    }\n  }, mdx(\"a\", {\n    parentName: \"h3\",\n    \"href\": \"#on-statements-1\",\n    \"aria-label\": \"on statements 1 permalink\",\n    \"className\": \"anchor before\"\n  }, mdx(\"svg\", {\n    parentName: \"a\",\n    \"aria-hidden\": \"true\",\n    \"focusable\": \"false\",\n    \"height\": \"16\",\n    \"version\": \"1.1\",\n    \"viewBox\": \"0 0 16 16\",\n    \"width\": \"16\"\n  }, mdx(\"path\", {\n    parentName: \"svg\",\n    \"fillRule\": \"evenodd\",\n    \"d\": \"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"\n  }))), \"On Statements\"), mdx(\"p\", null, \"Looking at \", mdx(\"a\", {\n    parentName: \"p\",\n    \"href\": \"https://github.com/NUbots/NUbots/blob/5bb3e76d2a32d9e9f4367fb25b3338f032727c51/module/input/SensorFilter/src/SensorFilter.cpp\"\n  }, mdx(\"inlineCode\", {\n    parentName: \"a\"\n  }, \"SensorFilter.cpp\")), \" we can see some examples of NUClear on statements.\"), mdx(\"p\", null, \"The first on statement is located at \", mdx(\"a\", {\n    parentName: \"p\",\n    \"href\": \"https://github.com/NUbots/NUbots/blob/5bb3e76d2a32d9e9f4367fb25b3338f032727c51/module/input/SensorFilter/src/SensorFilter.cpp#L91\"\n  }, \"line 94\"), \" of \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"SensorFilter.cpp\"), \".\"), mdx(\"pre\", null, mdx(\"code\", {\n    parentName: \"pre\",\n    \"className\": \"language-cpp\"\n  }, \" on<Configuration>(\\\"SensorFilter.yaml\\\").then([this](const Configuration& config) {\\n    log_level = cfg[\\\"log_level\\\"].as<NUClear::LogLevel>();\\n    // Button config\\n    config.buttons.debounceThreshold = cfg[\\\"buttons\\\"][\\\"debounce_threshold\\\"].as<int>();\\n    ...\\n});\\n\")), mdx(\"p\", null, \"The DSL request is \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"on<Configuration>\"), \". This means the runtime argument here is \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"(\\\"SensorFilter.yaml\\\")\"), \". This is the \", mdx(\"a\", {\n    parentName: \"p\",\n    \"href\": \"https://github.com/NUbots/NUbots/blob/5bb3e76d2a32d9e9f4367fb25b3338f032727c51/module/input/SensorFilter/data/config/SensorFilter.yaml\"\n  }, \"configuration file\"), \". The callback is\"), mdx(\"pre\", null, mdx(\"code\", {\n    parentName: \"pre\",\n    \"className\": \"language-cpp\"\n  }, \"then([this](const Configuration& config) {\\n    log_level = cfg[\\\"log_level\\\"].as<NUClear::LogLevel>();\\n    // Button config\\n    config.buttons.debounceThreshold = cfg[\\\"buttons\\\"][\\\"debounce_threshold\\\"].as<int>();\\n    ...\\n});\\n\")), mdx(\"p\", null, \"The \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"const Configuration& config\"), \" is a parameter of type \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"Configuration\"), \". We can see examples of how this type works in the lines after it. \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"cfg[\\\"buttons\\\"][\\\"debounce_threshold\\\"].as<int>()\"), \" finds the value labelled as \", mdx(\"a\", {\n    parentName: \"p\",\n    \"href\": \"https://github.com/NUbots/NUbots/blob/5bb3e76d2a32d9e9f4367fb25b3338f032727c51/module/input/SensorFilter/data/config/SensorFilter.yaml#L4\"\n  }, \"[\\\"buttons\\\"][\\\"debounce_threshold\\\"] in the configuration file\"), \" and retrieves it as an \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"int\"), \" type.\"), mdx(\"p\", null, \"This value is then stored in the \", mdx(\"a\", {\n    parentName: \"p\",\n    \"href\": \"https://github.com/NUbots/NUbots/blob/5bb3e76d2a32d9e9f4367fb25b3338f032727c51/module/input/SensorFilter/src/SensorFilter.hpp#L126\"\n  }, \"member variable\"), \" \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"debounceThreshold\"), \" in the struct \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"buttons\"), \".\"), mdx(\"p\", null, \"This reaction is used at startup to set many variables from a configuration file. The \", mdx(\"a\", {\n    parentName: \"p\",\n    \"href\": \"https://github.com/NUbots/NUbots/blob/5bb3e76d2a32d9e9f4367fb25b3338f032727c51/module/input/SensorFilter/src/SensorFilter.cpp#L188\"\n  }, \"next on statement\"), \" does this as well, but with the \", mdx(\"a\", {\n    parentName: \"p\",\n    \"href\": \"https://github.com/NUbots/NUbots/blob/5bb3e76d2a32d9e9f4367fb25b3338f032727c51/module/input/SensorFilter/data/config/FootDownNetwork.yaml\"\n  }, mdx(\"inlineCode\", {\n    parentName: \"a\"\n  }, \"FootDownNetwork.yaml\")), \" configuration file.\"), mdx(\"p\", null, \"The \", mdx(\"a\", {\n    parentName: \"p\",\n    \"href\": \"https://github.com/NUbots/NUbots/blob/5bb3e76d2a32d9e9f4367fb25b3338f032727c51/module/input/SensorFilter/src/SensorFilter.cpp#L193\"\n  }, \"third on statement\"), \" uses the DSL words \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"Last\"), \", \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"Trigger\"), \", \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"With\"), \" and \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"Single\"), \".\"), mdx(\"pre\", null, mdx(\"code\", {\n    parentName: \"pre\",\n    \"className\": \"language-cpp\"\n  }, \"on<Last<20, Trigger<RawSensors>>, With<KinematicsModel>, Single>().then(\\n            [this](const std::list<std::shared_ptr<const RawSensors>>& sensors, const KinematicsModel& model) {\\n    ...\\n});\\n\")), mdx(\"p\", null, \"The DSL request is \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"on<Last<20, Trigger<RawSensors>>, With<KinematicsModel>, Single>\"), \". This says that we will create a task for this reaction when we receive a \", mdx(\"a\", {\n    parentName: \"p\",\n    \"href\": \"https://github.com/NUbots/NUbots/blob/5bb3e76d2a32d9e9f4367fb25b3338f032727c51/shared/message/platform/RawSensors.proto\"\n  }, mdx(\"inlineCode\", {\n    parentName: \"a\"\n  }, \"RawSensors\")), \" message. The last 20 received \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"RawSensors\"), \" messages will be stored in a \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"std::list\"), \". \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"With<KinematicsModel>\"), \" will get the last available \", mdx(\"a\", {\n    parentName: \"p\",\n    \"href\": \"https://github.com/NUbots/NUbots/blob/5bb3e76d2a32d9e9f4367fb25b3338f032727c51/shared/message/motion/KinematicsModel.proto\"\n  }, mdx(\"inlineCode\", {\n    parentName: \"a\"\n  }, \"KinematicsModel\")), \" message. The \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"KinematicsModel\"), \" message is emitted once \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"on<Configuration>\"), \" in the \", mdx(\"a\", {\n    parentName: \"p\",\n    \"href\": \"https://github.com/NUbots/NUbots/blob/5bb3e76d2a32d9e9f4367fb25b3338f032727c51/module/motion/KinematicsConfiguration/src/KinematicsConfiguration.cpp\"\n  }, \"KinematicsConfiguration module\"), \" to provide measurements for the robot. Finally, the \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"Single\"), \" word is used to only run one task for this reaction at any given time. If a \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"RawSensors\"), \" message is received while a task is already running, a new task will \", mdx(\"strong\", {\n    parentName: \"p\"\n  }, \"not\"), \" be created.\"), mdx(\"p\", null, \"None of the words used require runtime arguments, so we do not have any here. The callback is\"), mdx(\"pre\", null, mdx(\"code\", {\n    parentName: \"pre\"\n  }, \"then(\\n                [this](const std::list<std::shared_ptr<const RawSensors>>& sensors, const KinematicsModel& model) {\\n    ...\\n});\\n\")), mdx(\"p\", null, \"The first parameter for this lambda statement is a \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"std::list\"), \". This is because the word \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"Last\"), \" is used. The list will contain those last 20 received messages as specified in the DSL request. It is also valid to use a \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"std::vector\"), \" for this parameter. The \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"KinematicsModel\"), \" parameter is not a list because \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"Last\"), \" only applies to the message in the \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"Trigger\"), \".\"), mdx(\"p\", null, \"The \", mdx(\"a\", {\n    parentName: \"p\",\n    \"href\": \"https://github.com/NUbots/NUbots/blob/5bb3e76d2a32d9e9f4367fb25b3338f032727c51/module/input/SensorFilter/src/SensorFilter.cpp#L339\"\n  }, \"next on statement\"), \" in \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"SensorFilter.cpp\"), \" uses \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"Trigger\"), \", \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"Optional\"), \", \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"With\"), \", \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"Single\"), \", and \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"Priority\"), \".\"), mdx(\"pre\", null, mdx(\"code\", {\n    parentName: \"pre\"\n  }, \"update_loop =\\n            on<Trigger<RawSensors>, Optional<With<Sensors>>, With<KinematicsModel>, Single, Priority::HIGH>()\\n                .then(\\n                    \\\"Main Sensors Loop\\\",\\n                    [this](const RawSensors& input,\\n                           const std::shared_ptr<const Sensors>& previousSensors,\\n                           const KinematicsModel& kinematicsModel) {\\n                        auto sensors = std::make_unique<Sensors>();\\n                        ...\\n});\\n\")), mdx(\"p\", null, \"The DSL request is \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"on<Trigger<RawSensors>, Optional<With<Sensors>>, With<KinematicsModel>, Single, Priority::HIGH>\"), \". This will create a task when \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"RawSensors\"), \" and \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"KinematicsModel\"), \" messages are received. We do not need to have received a \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"Sensors\"), \" message since it is \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"Optional\"), \". If a task is already running, a new task will not be created since the \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"Single\"), \" word is present. \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"Priority::HIGH\"), \" specifies that the PowerPlant should give this a \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"HIGH\"), \" priority when scheduling.\"), mdx(\"p\", null, \"Another aspect of this reactor is the \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"update_loop\"), \" variable. This is a ReactionHandle type and can be found in the \", mdx(\"a\", {\n    parentName: \"p\",\n    \"href\": \"https://github.com/NUbots/NUbots/blob/5bb3e76d2a32d9e9f4367fb25b3338f032727c51/module/input/SensorFilter/src/SensorFilter.hpp#L179\"\n  }, \"header file\"), \". The reaction can be enabled by calling \", mdx(\"a\", {\n    parentName: \"p\",\n    \"href\": \"https://github.com/NUbots/NUbots/blob/5bb3e76d2a32d9e9f4367fb25b3338f032727c51/module/input/SensorFilter/src/SensorFilter.cpp#L276\"\n  }, mdx(\"inlineCode\", {\n    parentName: \"a\"\n  }, \"update_loop.enable()\")), \" and disabled by calling \", mdx(\"a\", {\n    parentName: \"p\",\n    \"href\": \"https://github.com/NUbots/NUbots/blob/5bb3e76d2a32d9e9f4367fb25b3338f032727c51/module/input/SensorFilter/src/SensorFilter.cpp#L184\"\n  }, mdx(\"inlineCode\", {\n    parentName: \"a\"\n  }, \"update_loop.disable()\")), \".\"), mdx(\"p\", null, \"As expected, our callback has \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"const RawSensors& input\"), \" and \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"const KinematicsModel& kinematicsModel\"), \" since we asked for the \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"RawSensors\"), \" and the \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"KinematicsModel\"), \" messages. The interesting part of this is the \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"std::shared_ptr<const Sensors> previousSensors\"), \". This will either be a \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"nullptr\"), \" or a valid Sensors message. \", mdx(\"a\", {\n    parentName: \"p\",\n    \"href\": \"https://github.com/NUbots/NUbots/blob/5bb3e76d2a32d9e9f4367fb25b3338f032727c51/module/input/SensorFilter/src/SensorFilter.cpp#L408\"\n  }, \"There are checks in the function to see if the pointer is null\"), \" and this determines how the function behaves.\"), mdx(\"p\", null, \"Looking at line 133 of \", mdx(\"a\", {\n    parentName: \"p\",\n    \"href\": \"https://github.com/NUbots/NUbots/blob/105b78ad6655801f5f74d029cbd169ba8e8cb5e8/module/behaviour/tools/ScriptTuner/src/ScriptTuner.cpp#L133\"\n  }, mdx(\"inlineCode\", {\n    parentName: \"a\"\n  }, \"ScriptTuner.cpp\")), \" we can see an example of an \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"on<IO>\"), \" reaction.\"), mdx(\"pre\", null, mdx(\"code\", {\n    parentName: \"pre\",\n    \"className\": \"language-cpp\"\n  }, \"on<IO>(STDIN_FILENO, IO::READ).then([this] {\\n    // Get the character the user has typed\\n    switch (getch()) {\\n        ...\\n    }\\n\\n    // Update whatever visual changes we made\\n    refreshView();\\n});\\n\")), mdx(\"p\", null, \"In this case the DSL request is \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"on<IO>\"), \" and the runtime arguments are \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"(STDIN_FILENO, IO::READ)\"), \" which directs the PowerPlant to monitor for new data to read on the standard input file (i.e. the keybaord). Finally, the callback is\"), mdx(\"pre\", null, mdx(\"code\", {\n    parentName: \"pre\",\n    \"className\": \"language-cpp\"\n  }, \"then([this] {\\n    // Get the character the user has typed\\n    switch (getch()) {\\n        ...\\n    }\\n\\n    // Update whatever visual changes we made\\n    refreshView();\\n});\\n\")), mdx(\"h3\", {\n    \"id\": \"emit-statements-1\",\n    \"style\": {\n      \"position\": \"relative\"\n    }\n  }, mdx(\"a\", {\n    parentName: \"h3\",\n    \"href\": \"#emit-statements-1\",\n    \"aria-label\": \"emit statements 1 permalink\",\n    \"className\": \"anchor before\"\n  }, mdx(\"svg\", {\n    parentName: \"a\",\n    \"aria-hidden\": \"true\",\n    \"focusable\": \"false\",\n    \"height\": \"16\",\n    \"version\": \"1.1\",\n    \"viewBox\": \"0 0 16 16\",\n    \"width\": \"16\"\n  }, mdx(\"path\", {\n    parentName: \"svg\",\n    \"fillRule\": \"evenodd\",\n    \"d\": \"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"\n  }))), \"Emit Statements\"), mdx(\"p\", null, \"An example of local emission can be seen in \", mdx(\"a\", {\n    parentName: \"p\",\n    \"href\": \"https://github.com/NUbots/NUbots/blob/5bb3e76d2a32d9e9f4367fb25b3338f032727c51/module/input/SensorFilter/src/SensorFilter.cpp#L788\"\n  }, mdx(\"inlineCode\", {\n    parentName: \"a\"\n  }, \"SensorFilter.cpp\")), \" where we call\"), mdx(\"pre\", null, mdx(\"code\", {\n    parentName: \"pre\",\n    \"className\": \"language-cpp\"\n  }, \"emit(std::move(sensors));\\n\")), mdx(\"p\", null, \"This emits a \", mdx(\"a\", {\n    parentName: \"p\",\n    \"href\": \"https://github.com/NUbots/NUbots/blob/5bb3e76d2a32d9e9f4367fb25b3338f032727c51/shared/message/input/Sensors.proto\"\n  }, mdx(\"inlineCode\", {\n    parentName: \"a\"\n  }, \"Sensors\")), \" message. This can then be received by reactors waiting for a \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"Sensors\"), \" message to trigger the reaction.\"), mdx(\"p\", null, \"Looking at line 236 of \", mdx(\"a\", {\n    parentName: \"p\",\n    \"href\": \"https://github.com/NUbots/NUbots/blob/e7db7154a689ab076041375894b3baf1d53a2587/module/support/NUsight/src/GameController.cpp#L236\"\n  }, mdx(\"inlineCode\", {\n    parentName: \"a\"\n  }, \"GameController.cpp\")), \", we can see an example of NUClear network emission.\"), mdx(\"pre\", null, mdx(\"code\", {\n    parentName: \"pre\",\n    \"className\": \"language-cpp\"\n  }, \"powerplant.emit_shared<Scope::NETWORK>(std::move(gameState), \\\"nusight\\\", true);\\n\")), mdx(\"p\", null, \"This tells the PowerPlant to emit something across the network. In this case, we are emitting \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"gameState\"), \", which is a \", mdx(\"a\", {\n    parentName: \"p\",\n    \"href\": \"https://github.com/NUbots/NUbots/blob/e7db7154a689ab076041375894b3baf1d53a2587/shared/message/input/GameState.proto\"\n  }, mdx(\"inlineCode\", {\n    parentName: \"a\"\n  }, \"GameState\")), \" message. The target is \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"nusight\"), \", signifying that it will be received by NUsight. \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"true\"), \" signifies that it is reliable.\"), mdx(\"p\", null, \"Looking at line 112 of \", mdx(\"a\", {\n    parentName: \"p\",\n    \"href\": \"https://github.com/NUbots/NUbots/blob/e7db7154a689ab076041375894b3baf1d53a2587/module/behaviour/tools/ScriptTuner/src/ScriptTuner.cpp#L112\"\n  }, mdx(\"inlineCode\", {\n    parentName: \"a\"\n  }, \"ScriptTuner.cpp\")), \", we can see an example of an \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"INITIALIZE\"), \" scoped emit statement.\"), mdx(\"pre\", null, mdx(\"code\", {\n    parentName: \"pre\",\n    \"className\": \"language-cpp\"\n  }, \"emit<Scope::INITIALIZE>(std::make_unique<RegisterAction>(RegisterAction{\\n    id,\\n    \\\"Script Tuner\\\",\\n    {std::pair<float, std::set<LimbID>>(\\n        1, {LimbID::LEFT_LEG, LimbID::RIGHT_LEG, LimbID::LEFT_ARM, LimbID::RIGHT_ARM, LimbID::HEAD})},\\n    [this](const std::set<LimbID>&) {},\\n    [this](const std::set<LimbID>&) {},\\n    [this](const std::set<ServoID>&) {}}));\\n\")), mdx(\"p\", null, \"This tells the PowerPlant to emit something at system initialization. In this case, we are emitting a \", mdx(\"a\", {\n    parentName: \"p\",\n    \"href\": \"https://github.com/NUbots/NUbots/blob/e7db7154a689ab076041375894b3baf1d53a2587/shared/utility/behaviour/Action.h#L34\"\n  }, mdx(\"inlineCode\", {\n    parentName: \"a\"\n  }, \"RegisterAction\")), \" which registers the \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"ScriptTuner\"), \" module with the subsumption system.\"));\n}\n;\nMDXContent.isMDXComponent = true;","tableOfContents":{"items":[{"url":"#components","title":"Components","items":[{"url":"#powerplant","title":"PowerPlant"},{"url":"#reactors","title":"Reactors"},{"url":"#reactions-and-tasks","title":"Reactions and Tasks"}]},{"url":"#nuclear-dsl","title":"NUClear DSL","items":[{"url":"#on-statements","title":"On Statements"},{"url":"#emit-statements","title":"Emit Statements"}]},{"url":"#managing-reactions","title":"Managing Reactions"},{"url":"#nuclear-roles","title":"NUClear Roles","items":[{"url":"#directories","title":"Directories"},{"url":"#roles","title":"Roles"},{"url":"#nbs-files","title":"NBS Files"},{"url":"#neutrons","title":"Neutrons"}]},{"url":"#examples","title":"Examples","items":[{"url":"#on-statements-1","title":"On Statements"},{"url":"#emit-statements-1","title":"Emit Statements"}]}]},"frontmatter":{"section":"System","chapter":"Foundations","title":"NUClear","description":"Introduction to NUClear and how it is used in the NUbots codebase.","keywords":null,"slug":"/system/foundations/nuclear","hidden":null},"childNUbookContributions":{"authors":[{"name":"Ysobel Sims","username":"ysims"},{"name":"Cameron Murtagh","username":"CMurtagh-LGTM"}],"lastCommit":{"date":"2023-10-01T00:09:49.000Z","hash":"99499b56403dd9c4c15d116ca4146f4e0b2d98b4"}}}},"pageContext":{"mdxPath":"src/book/02-system/01-foundations/04-nuclear.mdx","id":"ceeef6dc-5870-5eb3-b6ad-615ce40c63ba","next":{"chapter":"Foundations","title":"Mathematics","description":"Detailed explanation of how mathematics is written in the NUbots codebase.","slug":"/system/foundations/mathematics","hidden":null},"previous":{"chapter":"Foundations","title":"Continuous Integration","description":"The NUbots continuous integration system.","slug":"/system/foundations/ci-system","hidden":null},"menu":[{"title":"Team","slug":"/team/introduction","chapters":[{"title":"Introduction","slug":"/team/introduction","pages":[{"title":"Introduction to NUbots","slug":"/team/introduction","hidden":null},{"title":"Areas of Research","slug":"/team/areas-of-research","hidden":null},{"title":"Current Team","slug":"/team/current-members","hidden":null}],"hidden":false},{"title":"Joining the Team","slug":"/team/how-we-work","pages":[{"title":"How We Work","slug":"/team/how-we-work","hidden":null},{"title":"How to Join NUbots","slug":"/team/how-to-join","hidden":null},{"title":"Lab Induction","slug":"/team/induction","hidden":null}],"hidden":false},{"title":"Community","slug":"/team/sponsors","pages":[{"title":"Sponsors","slug":"/team/sponsors","hidden":null},{"title":"Connect","slug":"/team/connect","hidden":null}],"hidden":false},{"title":"History","slug":"/team/history","pages":[{"title":"Team History","slug":"/team/history","hidden":null},{"title":"Past Members","slug":"/team/past-members","hidden":null},{"title":"Publications","slug":"/team/publications","hidden":null}],"hidden":false},{"title":"RoboCup","slug":"/team/robocup","pages":[{"title":"RoboCup","slug":"/team/robocup","hidden":null},{"title":"Resources","slug":"/team/robocup/resources","hidden":null},{"title":"Debriefs","slug":"/team/robocup/debriefs","hidden":null}],"hidden":false}],"hidden":false},{"title":"System","slug":"/system/foundations/overview","chapters":[{"title":"Foundations","slug":"/system/foundations/overview","pages":[{"title":"Overview","slug":"/system/foundations/overview","hidden":null},{"title":"Build System","slug":"/system/foundations/build-system","hidden":null},{"title":"Continuous Integration","slug":"/system/foundations/ci-system","hidden":null},{"title":"NUClear","slug":"/system/foundations/nuclear","hidden":null},{"title":"Mathematics","slug":"/system/foundations/mathematics","hidden":null},{"title":"Configuration and Script System","slug":"/system/foundations/config-script","hidden":null},{"title":"Director","slug":"/system/foundations/director","hidden":null}],"hidden":false},{"title":"Subsystems","slug":"/system/subsystems/input","pages":[{"title":"Input","slug":"/system/subsystems/input","hidden":null},{"title":"Odometry","slug":"/system/subsystems/odometry","hidden":null},{"title":"Localisation","slug":"/system/subsystems/localisation","hidden":null},{"title":"Motion","slug":"/system/subsystems/motion","hidden":null},{"title":"Vision","slug":"/system/subsystems/vision","hidden":null},{"title":"Behaviour","slug":"/system/subsystems/behaviour","hidden":null},{"title":"Logging","slug":"/system/subsystems/logging","hidden":null}],"hidden":false},{"title":"Tools","slug":"/system/tools/nusight","pages":[{"title":"NUsight","slug":"/system/tools/nusight","hidden":null},{"title":"NUbook","slug":"/system/tools/nubook","hidden":null},{"title":"NUpbr","slug":"/system/tools/nupbr","hidden":null},{"title":"NUgan","slug":"/system/tools/nugan","hidden":null},{"title":"System Configuration","slug":"/system/tools/system_configuration","hidden":null},{"title":"NatNet SDK","slug":"/system/tools/natnet_sdk","hidden":null}],"hidden":false},{"title":"Hardware","slug":"/system/hardware/overview","pages":[{"title":"Overview and Specifications","slug":"/system/hardware/overview","hidden":null}],"hidden":false},{"title":"Modules","slug":"/system/modules/actuation/","pages":[{"title":"Actuation","slug":"/system/modules/actuation/","hidden":null},{"title":"Extension","slug":"/system/modules/extension/","hidden":null},{"title":"Input","slug":"/system/modules/input/","hidden":null},{"title":"Localisation","slug":"/system/modules/localisation/","hidden":null},{"title":"Nbs","slug":"/system/modules/nbs/","hidden":null},{"title":"Network","slug":"/system/modules/network/","hidden":null},{"title":"Output","slug":"/system/modules/output/","hidden":null},{"title":"Planning","slug":"/system/modules/planning/","hidden":null},{"title":"Platform","slug":"/system/modules/platform/","hidden":null},{"title":"Purpose","slug":"/system/modules/purpose/","hidden":null},{"title":"Skill","slug":"/system/modules/skill/","hidden":null},{"title":"Strategy","slug":"/system/modules/strategy/","hidden":null},{"title":"Support","slug":"/system/modules/support/","hidden":null},{"title":"Tools","slug":"/system/modules/tools/","hidden":null},{"title":"Vision","slug":"/system/modules/vision/","hidden":null}],"hidden":false}],"hidden":false},{"title":"Guides","slug":"/guides/main/getting-started","chapters":[{"title":"Main Codebase","slug":"/guides/main/getting-started","pages":[{"title":"Getting Started","slug":"/guides/main/getting-started","hidden":null},{"title":"NUClear","slug":"/guides/main/nuclear-tutorial","hidden":null},{"title":"Running and Tuning Scripts","slug":"/guides/main/tuning-and-running-scripts","hidden":null},{"title":"Maintaining Subsystems","slug":"/guides/main/maintaining-subsystems","hidden":null},{"title":"Data Recording and Playback","slug":"/guides/main/data-recording-playback","hidden":null},{"title":"Camera Calibration","slug":"/guides/main/camera-calibration","hidden":null},{"title":"Onboarding Workshop","slug":"/guides/main/onboarding","hidden":null}],"hidden":false},{"title":"Tools","slug":"/guides/tools/nusight-contribution","pages":[{"title":"Contributing to NUsight","slug":"/guides/tools/nusight-contribution","hidden":null},{"title":"Setting Up Webots","slug":"/guides/tools/webots-setup","hidden":null},{"title":"Visual Mesh Getting Started","slug":"/guides/tools/visualmesh","hidden":null},{"title":"Using NUpbr","slug":"/guides/tools/nupbr-guide","hidden":null},{"title":"GameController Setup","slug":"/guides/tools/gamecontroller","hidden":null}],"hidden":false},{"title":"Hardware","slug":"/guides/hardware/working-with-robots","pages":[{"title":"Working with Robots","slug":"/guides/hardware/working-with-robots","hidden":null},{"title":"Flashing a Robot","slug":"/guides/hardware/flashing","hidden":null},{"title":"Servo Setup and Calibration","slug":"/guides/hardware/servo-calibration","hidden":null},{"title":"Batteries","slug":"/guides/hardware/batteries","hidden":null},{"title":"DARwIn Op2 Robot Restoration and Calibration Guide","slug":"/guides/hardware/darwin-op2-guide","hidden":null}],"hidden":false},{"title":"General","slug":"/guides/general/learning-resources","pages":[{"title":"Learning Resources","slug":"/guides/general/learning-resources","hidden":null},{"title":"Contribution Workflow","slug":"/guides/general/contribute","hidden":null},{"title":"RoboCup Setup","slug":"/guides/general/robocup-setup","hidden":null},{"title":"Troubleshooting","slug":"/guides/general/troubleshooting","hidden":null},{"title":"Code Conventions","slug":"/guides/general/code-conventions","hidden":null},{"title":"Glossary","slug":"/guides/general/glossary","hidden":null}],"hidden":false}],"hidden":false},{"title":"Kitchen Sink","slug":"/kitchen-sink/headers","chapters":[{"title":"Markdown","slug":"/kitchen-sink/headers","pages":[{"title":"Headers","slug":"/kitchen-sink/headers","hidden":true},{"title":"Formatting and Paragraphs","slug":"/kitchen-sink/formatting-and-paragraphs","hidden":true},{"title":"Blockquotes","slug":"/kitchen-sink/blockquotes","hidden":true},{"title":"Alerts","slug":"/kitchen-sink/alerts","hidden":true},{"title":"Images","slug":"/kitchen-sink/images","hidden":true},{"title":"Lists","slug":"/kitchen-sink/lists","hidden":true},{"title":"Code","slug":"/kitchen-sink/code","hidden":true},{"title":"Math","slug":"/kitchen-sink/math","hidden":true},{"title":"Table of Contents","slug":"/kitchen-sink/table-of-contents","hidden":true},{"title":"Tables","slug":"/kitchen-sink/tables","hidden":true},{"title":"Collapsible Content","slug":"/kitchen-sink/collapsible","hidden":true},{"title":"GraphViz Diagrams","slug":"/kitchen-sink/graphviz-diagrams","hidden":true},{"title":"Referencing","slug":"/kitchen-sink/referencing","hidden":true}],"hidden":true}],"hidden":true}],"references":null,"hidden":null}},
    "staticQueryHashes": ["3715292327","445096115","466146812"]}