From bb1f3f08cf93facbf926e57384674441be7e2884 Mon Sep 17 00:00:00 2001
From: Mnikolenko Productengine <mnikolenko@productengine.com>
Date: Mon, 22 Apr 2024 14:56:52 +0300
Subject: Add demo script with idle and notification interactions

---
 indra/llui/llluafloater.cpp                        | 16 ++++++++--
 indra/llui/llluafloater.h                          |  2 ++
 indra/newview/llvoavatar.cpp                       | 30 +++++++++++++++++++
 indra/newview/scripts/lua/LLNotification.lua       | 15 ++++++++++
 .../newview/scripts/lua/luafloater_speedometer.xml | 35 ++++++++++++++++++++++
 .../scripts/lua/test_luafloater_speedometer.lua    | 26 ++++++++++++++++
 6 files changed, 122 insertions(+), 2 deletions(-)
 create mode 100644 indra/newview/scripts/lua/LLNotification.lua
 create mode 100644 indra/newview/scripts/lua/luafloater_speedometer.xml
 create mode 100644 indra/newview/scripts/lua/test_luafloater_speedometer.lua

diff --git a/indra/llui/llluafloater.cpp b/indra/llui/llluafloater.cpp
index e584a67a00..62e77fd556 100644
--- a/indra/llui/llluafloater.cpp
+++ b/indra/llui/llluafloater.cpp
@@ -35,6 +35,7 @@
 #include "lltexteditor.h"
 
 const std::string LISTENER_NAME("LLLuaFloater");
+const F32 IDLE_INTERVAL = 0.5;
 
 std::set<std::string> EVENT_LIST = {
     "commit",
@@ -47,14 +48,16 @@ std::set<std::string> EVENT_LIST = {
     "right_mouse_up",
     "post_build",
     "floater_close",
-    "keystroke"
+    "keystroke",
+    "idle"
 };
 
 LLLuaFloater::LLLuaFloater(const LLSD &key) :
     LLFloater(key),
     mDispatchListener(LLUUID::generateNewID().asString(), "action"),
     mReplyPumpName(key["reply"].asString()),
-    mReqID(key)
+    mReqID(key),
+    mIdleTimer(new LLTimer())
 {
     auto ctrl_lookup = [this](const LLSD &event, std::function<LLSD(LLUICtrl*,const LLSD&)> cb)
     {
@@ -166,6 +169,15 @@ BOOL LLLuaFloater::postBuild()
     return true;
 }
 
+void LLLuaFloater::draw()
+{
+    if (mIdleTimer->checkExpirationAndReset(IDLE_INTERVAL))
+    {
+        postEvent(LLSD(), "idle");
+    }
+    LLFloater::draw();
+}
+
 void LLLuaFloater::onClose(bool app_quitting)
 {
     postEvent(llsd::map("app_quitting", app_quitting), "floater_close");
diff --git a/indra/llui/llluafloater.h b/indra/llui/llluafloater.h
index ccc3ccb39b..36e65ac7fc 100644
--- a/indra/llui/llluafloater.h
+++ b/indra/llui/llluafloater.h
@@ -36,6 +36,7 @@ public:
     LLLuaFloater(const LLSD &key);
     BOOL postBuild();
     virtual ~LLLuaFloater();
+    void draw();
 
     void registerCallback(const std::string &ctrl_name, const std::string &event);
     void onClose(bool app_quitting);
@@ -48,6 +49,7 @@ public:
 private:
     LLReqID mReqID;
     LLDispatchListener mDispatchListener;
+    std::unique_ptr<LLTimer> mIdleTimer;
 
     std::string mReplyPumpName;
 };
diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp
index 9579a5e4b1..3074990a9b 100644
--- a/indra/newview/llvoavatar.cpp
+++ b/indra/newview/llvoavatar.cpp
@@ -114,6 +114,7 @@
 #include "llskinningutil.h"
 
 #include "llperfstats.h"
+#include "lleventapi.h"
 
 #include <boost/lexical_cast.hpp>
 
@@ -11599,4 +11600,33 @@ F32 LLVOAvatar::getAverageGPURenderTime()
     return ret;
 }
 
+class LLVOAvatarListener : public LLEventAPI
+{
+  public:
+    LLVOAvatarListener() : LLEventAPI("LLVOAvatar", "LLVOAvatar listener to retrieve avatar info")
+    {
+        add("getSpeed",
+            "Return the avatar movement speed in the XY plane",
+            &LLVOAvatarListener::getSpeed,
+            LLSD().with("reply", LLSD()));
+        add("isInAir",
+            "Return the info whether avatar is in the air, and if so the time in the air",
+            &LLVOAvatarListener::isInAir,
+            LLSD().with("reply", LLSD()));
+    }
+
+  private:
+    void getSpeed(const LLSD &request) const
+    {
+        LLVector3 avatar_velocity = gAgentAvatarp->getCharacterVelocity() * gAgentAvatarp->getTimeDilation();
+        avatar_velocity.mV[VZ] = 0.f;
+        Response response(llsd::map("value", avatar_velocity.magVec()), request);
+    }
+    void isInAir(const LLSD &request) const
+    {
+        Response response(llsd::map("value", gAgentAvatarp->mInAir, 
+                                    "duration", gAgentAvatarp->mInAir ? gAgentAvatarp->mTimeInAir.getElapsedTimeF32() : 0), request);
+    }
+};
 
+static LLVOAvatarListener VOAvatarListener;
diff --git a/indra/newview/scripts/lua/LLNotification.lua b/indra/newview/scripts/lua/LLNotification.lua
new file mode 100644
index 0000000000..f47730d1cc
--- /dev/null
+++ b/indra/newview/scripts/lua/LLNotification.lua
@@ -0,0 +1,15 @@
+-- Engage the LLNotificationsListener LLEventAPI
+
+leap = require 'leap'
+
+local LLNotification = {}
+
+function LLNotification.add(name, substitutions)
+    leap.send('LLNotifications', {op='requestAdd', name=name, substitutions=substitutions})
+end
+
+function LLNotification.requestAdd(name, substitutions)
+    return leap.request('LLNotifications', {op='requestAdd', name=name, substitutions=substitutions})['response']
+end
+
+return LLNotification
diff --git a/indra/newview/scripts/lua/luafloater_speedometer.xml b/indra/newview/scripts/lua/luafloater_speedometer.xml
new file mode 100644
index 0000000000..54b99c7d48
--- /dev/null
+++ b/indra/newview/scripts/lua/luafloater_speedometer.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<floater
+ legacy_header_height="18"
+ height="60"
+ layout="topleft"
+ name="lua_speedometer"
+ title="Speedometer"
+ can_minimize="false"
+ width="170">
+    <text
+     type="string"
+     follows="left|top"     
+     font="SansSerifBold"
+     font.size="Huge"
+     text_color="White"
+     layout="topleft"
+     top="25"
+     left_delta="30"
+     width="70"
+     height="30"
+     name="speed_lbl"/>
+    <text
+     type="string"
+     follows="left|top"
+     width="55"
+     height="30"
+     font="SansSerifBold"
+     font.size="Huge"
+     text_color="White"
+     layout="topleft"
+     left_pad="2"
+     name="mps_lbl">
+      m/s
+    </text> 
+</floater>
diff --git a/indra/newview/scripts/lua/test_luafloater_speedometer.lua b/indra/newview/scripts/lua/test_luafloater_speedometer.lua
new file mode 100644
index 0000000000..610401ae44
--- /dev/null
+++ b/indra/newview/scripts/lua/test_luafloater_speedometer.lua
@@ -0,0 +1,26 @@
+local Floater = require 'Floater'
+local startup = require 'startup'
+inspect = require 'inspect'
+leap = require 'leap'
+LLNotification = require 'LLNotification'
+local max_speed = 0
+local flt = Floater:new("luafloater_speedometer.xml")
+startup.wait('STATE_STARTED')
+
+function flt:floater_close(event_data)
+    msg = "Registered max speed: " .. string.format("%.2f", max_speed) .. " m/s";
+    LLNotification.add('SystemMessageTip', {MESSAGE = msg})
+end
+
+function flt:idle(event_data)
+    local speed = leap.request('LLVOAvatar', {op='getSpeed'})['value']
+    flt:post({action="set_value", ctrl_name="speed_lbl", value = string.format("%.2f", speed)})
+    max_speed=math.max(max_speed, speed)
+end
+
+msg = 'Are you sure you want to run this "speedometer" script?'
+response = LLNotification.requestAdd('GenericAlertYesCancel', {MESSAGE = msg})
+
+if response.OK_okcancelbuttons then
+  flt:show()
+end
-- 
cgit v1.2.3