1/**
2 * Copyright (c) 2006-2023 LOVE Development Team
3 *
4 * This software is provided 'as-is', without any express or implied
5 * warranty. In no event will the authors be held liable for any damages
6 * arising from the use of this software.
7 *
8 * Permission is granted to anyone to use this software for any purpose,
9 * including commercial applications, and to alter it and redistribute it
10 * freely, subject to the following restrictions:
11 *
12 * 1. The origin of this software must not be misrepresented; you must not
13 * claim that you wrote the original software. If you use this software
14 * in a product, an acknowledgment in the product documentation would be
15 * appreciated but is not required.
16 * 2. Altered source versions must be plainly marked as such, and must not be
17 * misrepresented as being the original software.
18 * 3. This notice may not be removed or altered from any source distribution.
19 **/
20
21#include "Event.h"
22
23using love::thread::Mutex;
24using love::thread::Lock;
25
26namespace love
27{
28namespace event
29{
30
31Message::Message(const std::string &name, const std::vector<Variant> &vargs)
32 : name(name)
33 , args(vargs)
34{
35}
36
37Message::~Message()
38{
39}
40
41int Message::toLua(lua_State *L)
42{
43 luax_pushstring(L, name);
44
45 for (const Variant &v : args)
46 v.toLua(L);
47
48 return (int) args.size() + 1;
49}
50
51Message *Message::fromLua(lua_State *L, int n)
52{
53 std::string name = luax_checkstring(L, n);
54 std::vector<Variant> vargs;
55
56 int count = lua_gettop(L) - n;
57 n++;
58
59 Variant varg;
60
61 for (int i = 0; i < count; i++)
62 {
63 if (lua_isnoneornil(L, n+i))
64 break;
65
66 luax_catchexcept(L, [&]() {
67 vargs.push_back(Variant::fromLua(L, n+i));
68 });
69
70 if (vargs.back().getType() == Variant::UNKNOWN)
71 {
72 vargs.clear();
73 luaL_error(L, "Argument %d can't be stored safely\nExpected boolean, number, string or userdata.", n+i);
74 return nullptr;
75 }
76 }
77
78 return new Message(name, vargs);
79}
80
81Event::~Event()
82{
83}
84
85void Event::push(Message *msg)
86{
87 Lock lock(mutex);
88 msg->retain();
89 queue.push(msg);
90}
91
92bool Event::poll(Message *&msg)
93{
94 Lock lock(mutex);
95 if (queue.empty())
96 return false;
97 msg = queue.front();
98 queue.pop();
99 return true;
100}
101
102void Event::clear()
103{
104 Lock lock(mutex);
105 while (!queue.empty())
106 {
107 // std::queue::pop will remove the first (front) element.
108 queue.front()->release();
109 queue.pop();
110 }
111}
112
113} // event
114} // love
115