{"id":2452,"date":"2026-05-12T10:18:43","date_gmt":"2026-05-12T09:18:43","guid":{"rendered":"https:\/\/coding4phone.com\/?p=2452"},"modified":"2026-05-12T10:18:44","modified_gmt":"2026-05-12T09:18:44","slug":"embarquer-un-moteur-de-script-dans-une-app-net-maui-logique-dynamique-commandes-ble-sans-mise-a-jour-de-lapp","status":"publish","type":"post","link":"https:\/\/coding4phone.com\/?p=2452","title":{"rendered":"Embarquer un moteur de script dans une app .NET MAUI \u2014 logique dynamique, commandes BLE, sans mise \u00e0 jour de l&rsquo;app"},"content":{"rendered":"\n<h2 class=\"wp-block-heading\">Le point de d\u00e9part<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\"><a href=\"https:\/\/www.mogwai.eu.com\" target=\"_blank\" rel=\"noreferrer noopener\">MOGWAI<\/a> est un moteur de script RPN open-source \u00e0 pile pour .NET, que je d\u00e9veloppe et utilise en production depuis plusieurs ann\u00e9es. Si vous n&rsquo;\u00eates pas familier avec la notation polonaise inverse (RPN), pensez au mod\u00e8le d&rsquo;ex\u00e9cution des calculatrices HP : les op\u00e9randes sont empil\u00e9s, et les op\u00e9rations les consomment. MOGWAI \u00e9tend ce mod\u00e8le en un v\u00e9ritable langage de script avec des fonctions, des variables, des boucles, des timers et des liaisons vers les applications h\u00f4tes.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Pendant longtemps, MOGWAI vivait dans des contextes desktop et serveur. Puis j&rsquo;ai eu besoin de l&#8217;embarquer dans une application mobile construite avec <a href=\"https:\/\/learn.microsoft.com\/fr-fr\/dotnet\/maui\/what-is-maui\" target=\"_blank\" rel=\"noreferrer noopener\">.NET MAUI<\/a>. Cet article d\u00e9crit pourquoi, comment, et \u00e0 quoi ressemble l&rsquo;architecture.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Le probl\u00e8me<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Mon application MAUI communique avec des appareils mat\u00e9riels via Bluetooth Low Energy (BLE). Les commandes envoy\u00e9es \u00e0 ces appareils ne sont pas triviales : elles d\u00e9pendent de param\u00e8tres de configuration, de l&rsquo;\u00e9tat de l&rsquo;appareil, et d&rsquo;une logique m\u00e9tier qui peut \u00e9voluer dans le temps.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">L&rsquo;approche na\u00efve consiste \u00e0 coder cette logique directement dans l&rsquo;app. \u00c7a fonctionne \u2014 jusqu&rsquo;\u00e0 ce que \u00e7a doive changer. Chaque modification implique un nouveau build, une nouvelle soumission sur les stores iOS et Android, et d&rsquo;attendre que les utilisateurs mettent \u00e0 jour. Pour une logique qui \u00e9volue fr\u00e9quemment, ce cycle est lent et fragile.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Ce que je voulais : une s\u00e9paration nette entre le moteur d&rsquo;ex\u00e9cution et la couche de communication (stables, versionn\u00e9s dans l&rsquo;app) d&rsquo;un c\u00f4t\u00e9, et la logique m\u00e9tier (flexible, mise \u00e0 jour ind\u00e9pendamment) de l&rsquo;autre.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Pourquoi un moteur de script et pas un fichier de configuration<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Un fichier de configuration g\u00e8re des valeurs statiques. Un moteur de script g\u00e8re de la logique.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Quand la commande \u00e0 envoyer d\u00e9pend de conditions, de s\u00e9quences d&rsquo;op\u00e9rations, ou de calculs sur l&rsquo;\u00e9tat \u00e0 l&rsquo;ex\u00e9cution, un fichier cl\u00e9-valeur ne suffit pas. Il faut quelque chose qui peut r\u00e9ellement ex\u00e9cuter du code. MOGWAI fournit cette couche : un environnement d&rsquo;ex\u00e9cution sandbox\u00e9 et embarquable qui prend un script en entr\u00e9e et produit un r\u00e9sultat en sortie.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">La s\u00e9paration est propre :<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>L&rsquo;app est responsable de la communication BLE, de l&rsquo;UI et du cycle de vie<\/li>\n\n\n\n<li>MOGWAI est responsable de la g\u00e9n\u00e9ration des commandes<\/li>\n\n\n\n<li>Les scripts sont responsables de la logique m\u00e9tier<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Chaque couche peut \u00e9voluer ind\u00e9pendamment.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Int\u00e9gration via NuGet<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Ajouter MOGWAI \u00e0 un projet MAUI est une simple r\u00e9f\u00e9rence NuGet. Le moteur est du .NET pur \u2014 pas de bindings natifs, pas de configuration sp\u00e9cifique \u00e0 la plateforme, pas de compilation conditionnelle. Il tourne sur iOS et Android sans modification.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">\/\/ Initialiser le moteur<br>var engine = new MogwaiEngine();<br><br>\/\/ Charger un script depuis un fichier ou une source distante<br>var script = await File.ReadAllTextAsync(scriptPath);<br><br>\/\/ Ex\u00e9cuter et r\u00e9cup\u00e9rer le r\u00e9sultat<br>var result = await engine.EvalAsync(script);<br><br>\/\/ Le r\u00e9sultat est le payload de la commande BLE<br>var command = result.AsBytes();<br>await bleService.SendAsync(command);<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">L&rsquo;initialisation du moteur est identique sur les deux plateformes. L&rsquo;ex\u00e9cution du script est identique. La gestion du r\u00e9sultat est identique. MAUI g\u00e8re la couche BLE sp\u00e9cifique \u00e0 la plateforme via son abstraction de services ; MOGWAI se situe enti\u00e8rement au-dessus, produisant les payloads qui sont ensuite envoy\u00e9s.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Les scripts viennent de l&rsquo;ext\u00e9rieur de l&rsquo;app<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Les scripts sont des fichiers <code>.mog<\/code> r\u00e9cup\u00e9r\u00e9s depuis un serveur distant ou charg\u00e9s depuis le stockage local. Quand la logique m\u00e9tier doit changer, seul le fichier script est mis \u00e0 jour \u2014 l&rsquo;application elle-m\u00eame n&rsquo;a pas besoin d&rsquo;\u00eatre modifi\u00e9e.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">C&rsquo;est l&rsquo;avantage op\u00e9rationnel cl\u00e9. Le moteur d&rsquo;ex\u00e9cution est stable et versionn\u00e9 dans l&rsquo;app. La logique est flexible et peut \u00eatre mise \u00e0 jour ind\u00e9pendamment. Pas de build, pas de soumission sur les stores, pas d&rsquo;attente de mise \u00e0 jour des utilisateurs.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">\u00c0 quoi ressemble l&rsquo;architecture<\/h2>\n\n\n\n<pre class=\"wp-block-preformatted\">Serveur distant \/ fichier local<br>        \u2193<br>   Script (fichier .mog)<br>        \u2193<br>  Moteur MOGWAI (.NET)<br>        \u2193<br>  Payload de commande (bytes)<br>        \u2193<br>   Service BLE (MAUI)<br>        \u2193<br>  Appareil mat\u00e9riel<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">L&rsquo;app r\u00e9cup\u00e8re le script, le passe au moteur, re\u00e7oit le r\u00e9sultat et le transmet \u00e0 la couche BLE. Chaque composant a une responsabilit\u00e9 unique.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">iOS et Android \u2014 le m\u00eame code<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Parce que MOGWAI est du .NET pur, il n&rsquo;y a rien de sp\u00e9cifique \u00e0 la plateforme \u00e0 g\u00e9rer au niveau de la couche de scripting. Le moteur tourne de fa\u00e7on identique sur les deux plateformes. Le seul code sp\u00e9cifique \u00e0 la plateforme dans l&rsquo;app est l&rsquo;impl\u00e9mentation du service BLE, que MAUI g\u00e8re d\u00e9j\u00e0 via son abstraction.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Cela a une importance pratique : une correction de bug ou un ajout de fonctionnalit\u00e9 dans la couche de scripting b\u00e9n\u00e9ficie simultan\u00e9ment aux deux plateformes, sans divergence \u00e0 g\u00e9rer.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Une note sur le threading<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Le pipeline d&rsquo;ex\u00e9cution de MOGWAI est enti\u00e8rement asynchrone, ce qui s&rsquo;adapte naturellement au mod\u00e8le async de MAUI. L&rsquo;ex\u00e9cution d&rsquo;un script ne bloque pas le thread UI. Un script en cours d&rsquo;ex\u00e9cution peut \u00eatre arr\u00eat\u00e9 \u00e0 tout moment en appelant <code>Engine.Halt()<\/code> \u2014 utile pour les sc\u00e9narios de timeout ou d&rsquo;annulation \u00e0 la demande de l&rsquo;utilisateur. Le moteur est con\u00e7u pour \u00eatre h\u00e9berg\u00e9 dans des boucles applicatives asynchrones, ce qui est exactement ce qu&rsquo;est une application mobile.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Conclusion<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Si vous avez de la logique dans votre application mobile qui \u00e9volue plus souvent que l&rsquo;application elle-m\u00eame, embarquer un moteur de script vaut la peine d&rsquo;\u00eatre envisag\u00e9. L&rsquo;int\u00e9gration NuGet se fait en une ligne. Le moteur tourne de fa\u00e7on identique sur iOS et Android. La capacit\u00e9 \u00e0 mettre \u00e0 jour la logique sans soumission sur les stores est un v\u00e9ritable avantage op\u00e9rationnel \u2014 surtout quand on cible les deux plateformes simultan\u00e9ment.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><a href=\"https:\/\/www.mogwai.eu.com\" target=\"_blank\" rel=\"noreferrer noopener\">MOGWAI<\/a> est open source, sous licence Apache 2.0, disponible sur <a href=\"https:\/\/www.nuget.org\/packages\/MOGWAI\" target=\"_blank\" rel=\"noreferrer noopener\">NuGet<\/a> et <a href=\"https:\/\/www.github.com\/sydney680928\/mogwai\" target=\"_blank\" rel=\"noreferrer noopener\">GitHub<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Le point de d\u00e9part MOGWAI est un moteur de script RPN open-source \u00e0 pile pour .NET, que je d\u00e9veloppe et utilise en production depuis plusieurs ann\u00e9es. Si vous n&rsquo;\u00eates pas familier avec la notation polonaise inverse (RPN), pensez au mod\u00e8le d&rsquo;ex\u00e9cution des calculatrices HP : les op\u00e9randes sont empil\u00e9s, et les op\u00e9rations les consomment. MOGWAI &#8230; <a title=\"Embarquer un moteur de script dans une app .NET MAUI \u2014 logique dynamique, commandes BLE, sans mise \u00e0 jour de l&rsquo;app\" class=\"read-more\" href=\"https:\/\/coding4phone.com\/?p=2452\" aria-label=\"En savoir plus sur Embarquer un moteur de script dans une app .NET MAUI \u2014 logique dynamique, commandes BLE, sans mise \u00e0 jour de l&rsquo;app\">Lire la suite<\/a><\/p>\n","protected":false},"author":1,"featured_media":2458,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"advanced_seo_description":"D\u00e9couvrez MOGWAI, un moteur de script RPN pour .NET, permettant de g\u00e9rer la logique m\u00e9tier de mani\u00e8re flexible dans vos apps mobiles.","jetpack_seo_html_title":"MOGWAI : Moteur de script RPN pour applications .NET MAUI","jetpack_seo_noindex":false,"jetpack_seo_schema_type":"","_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_wpcom_ai_launchpad_first_post":false,"_jetpack_feature_clip_id":0,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"Embarquer un moteur de script dans une app .NET MAUI. La logique dynamique, les commandes BLE, sans mise \u00e0 jour de l\u2019app...\n\n","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":false,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2},"_wpas_customize_per_network":false,"jetpack_post_was_ever_published":false},"categories":[5,6,48,50],"tags":[],"class_list":["post-2452","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-maui","category-mogwai","category-rpn","category-scripting"],"jetpack_publicize_connections":[],"jetpack_likes_enabled":true,"jetpack_sharing_enabled":true,"jetpack_shortlink":"https:\/\/wp.me\/pfoe4s-Dy","jetpack-related-posts":[],"jetpack_featured_media_url":"https:\/\/i0.wp.com\/coding4phone.com\/wp-content\/uploads\/2026\/05\/coding-4-phone-6a02ed8c444ec.png?fit=1024%2C1024&ssl=1","_links":{"self":[{"href":"https:\/\/coding4phone.com\/index.php?rest_route=\/wp\/v2\/posts\/2452","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/coding4phone.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/coding4phone.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/coding4phone.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/coding4phone.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=2452"}],"version-history":[{"count":6,"href":"https:\/\/coding4phone.com\/index.php?rest_route=\/wp\/v2\/posts\/2452\/revisions"}],"predecessor-version":[{"id":2460,"href":"https:\/\/coding4phone.com\/index.php?rest_route=\/wp\/v2\/posts\/2452\/revisions\/2460"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/coding4phone.com\/index.php?rest_route=\/wp\/v2\/media\/2458"}],"wp:attachment":[{"href":"https:\/\/coding4phone.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=2452"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/coding4phone.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=2452"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/coding4phone.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=2452"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}