summaryrefslogtreecommitdiff
path: root/indra/llcommon/lualistener.h
blob: 68131dfa27af715dea52df4c95e516ca57be45df (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
/**
 * @file   lualistener.h
 * @author Nat Goodspeed
 * @date   2024-02-06
 * @brief  Define LuaListener class
 * 
 * $LicenseInfo:firstyear=2024&license=viewerlgpl$
 * Copyright (c) 2024, Linden Research, Inc.
 * $/LicenseInfo$
 */

#if ! defined(LL_LUALISTENER_H)
#define LL_LUALISTENER_H

#include "llevents.h"               // LLTempBoundListener
#include "llsd.h"
#include "llthreadsafequeue.h"
#include <iosfwd>                   // std::ostream
#include <memory>                   // std::unique_ptr
#include <string>
#include <utility>                  // std::pair

struct lua_State;
class LLLeapListener;

/**
 * LuaListener is based on LLLeap. It serves an analogous function.
 *
 * Like LLLeap, each LuaListener instance also has an associated
 * LLLeapListener to respond to LLEventPump management commands.
 */
class LuaListener
{
public:
    LuaListener(lua_State* L);

    LuaListener(const LuaListener&) = delete;
    LuaListener& operator=(const LuaListener&) = delete;

    ~LuaListener();

    std::string getReplyName() const;
    std::string getCommandName() const;

    /**
     * LuaListener enqueues reply events from its LLLeapListener on mQueue.
     * Call getNext() to retrieve the next such event. Blocks the calling
     * coroutine if the queue is empty.
     */
    using PumpData = std::pair<std::string, LLSD>;
    PumpData getNext();

    friend std::ostream& operator<<(std::ostream& out, const LuaListener& self);

private:
    bool queueEvent(const std::string& pump, const LLSD& data);

    LLThreadSafeQueue<PumpData> mQueue;

    std::string mCoroName;
    std::unique_ptr<LLLeapListener> mListener;
    LLTempBoundListener mShutdownConnection;
};

#endif /* ! defined(LL_LUALISTENER_H) */