File: LuaConvert.h

package info (click to toggle)
freespace2 24.0.2%2Brepack-1
  • links: PTS, VCS
  • area: non-free
  • in suites: trixie
  • size: 43,188 kB
  • sloc: cpp: 583,107; ansic: 21,729; python: 1,174; sh: 464; makefile: 248; xml: 181
file content (149 lines) | stat: -rw-r--r-- 4,296 bytes parent folder | download | duplicates (4)
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
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
#ifndef LUAUTIL_H
#define LUAUTIL_H
#pragma once

#include "LuaHeaders.h"
#include "LuaException.h"
#include "LuaConvert.h"
#include "LuaReference.h"

#include "scripting/ade.h"

#include <cstdlib>

namespace luacpp {
/**
 * @brief Contains functions to convert C++ values to and from lua values.
 *
 * Currently the following types are supported:
 *   - `double`
 *   - `float`
 *   - `int`
 *   - `std::string`
 *   - `const char*` (only for pushing as using the pointer after it was removed from the stack is dangerous)
 *   - `bool`
 *   - `lua_CFunction`
 *   - `LuaTable` (only pop, use LuaValue version for pushing)
 *   - `LuaFunction` (only pop, use LuaValue version for pushing)
 *   - `LuaValue` (this will reference any value at the specified poition)
 */
namespace convert {

namespace internal {
bool isValidIndex(lua_State* state, int index);

bool ade_odata_helper(lua_State* L, int stackposition, size_t idx);
}

bool ade_odata_is_userdata_type(lua_State* L, int stackposition, size_t typeIdx, bool cleanup = true);

template<typename T>
bool ade_odata_is_userdata_type(lua_State* L, int stackposition, const T& obj_type) {
	return ade_odata_is_userdata_type(L, stackposition, obj_type.GetIdx());
}

void pushValue(lua_State* luaState, const double& value);

void pushValue(lua_State* luaState, const float& value);

void pushValue(lua_State* luaState, const int& value);

void pushValue(lua_State* luaState, const size_t& value);

void pushValue(lua_State* luaState, const std::string& value);

void pushValue(lua_State* luaState, const char* value);

void pushValue(lua_State* luaState, const bool& value);

void pushValue(lua_State* luaState, const lua_CFunction& value);

template<typename T>
void pushValue(lua_State* L, scripting::ade_odata_setter<T>&& value) {
	using namespace scripting;

	//WMC - char must be 1 byte, foo.
	static_assert(sizeof(char) == 1, "char must be 1 byte!");
	//WMC - step by step

	//Create new LUA object and get handle
	auto newod = (char*)lua_newuserdata(L, sizeof(T));
	//Create or get object metatable
	luaL_getmetatable(L, ::scripting::internal::getTableEntry(value.idx).Name);
	//Set the metatable for the object
	lua_setmetatable(L, -2);

	//Copy the actual object data to the Lua object
	new(newod) T(std::move(value.value));
}

/**
 * @brief Convenience function for string literals
 *
 * @param luaState The lua_State to push the values to
 * @param value The value which should be pushed.
 * @return void
 */
template<size_t N>
inline void pushValue(lua_State* luaState, const char(& value)[N]) {
	pushValue(luaState, (const char*)value);
}


bool popValue(lua_State* luaState, float& target, int stackposition = -1, bool remove = true);

bool popValue(lua_State* luaState, double& target, int stackposition = -1, bool remove = true);

bool popValue(lua_State* luaState, int& target, int stackposition = -1, bool remove = true);

bool popValue(lua_State* luaState, size_t& target, int stackposition = -1, bool remove = true);

bool popValue(lua_State* luaState, std::string& target, int stackposition = -1, bool remove = true);

bool popValue(lua_State* luaState, bool& target, int stackposition = -1, bool remove = true);

bool popValue(lua_State* luaState, lua_CFunction& target, int stackposition = -1, bool remove = true);

template <typename T>
bool popValue(lua_State* L, scripting::ade_odata_getter<T>&& od, int stackposition = -1, bool remove = true)
{
	// Use the helper to reduce the amount of code here
	if (!internal::ade_odata_helper(L, stackposition, od.idx)) {
		return false;
	}
	auto lua_ptr = lua_touserdata(L, stackposition);

	// Copy the value over by using the standard copy constructor
	*od.value_ptr = *reinterpret_cast<T*>(lua_ptr);

	if (remove) {
		lua_remove(L, stackposition);
	}

	return true;
}

template <typename T>
bool popValue(lua_State* L, scripting::ade_odata_ptr_getter<T>&& od, int stackposition = -1, bool remove = true)
{
	// Use the helper to reduce the amount of code here
	if (!internal::ade_odata_helper(L, stackposition, od.idx)) {
		return false;
	}
	auto lua_ptr = lua_touserdata(L, stackposition);

	// Only write the pointer value to the output pointer
	*od.value_ptr = reinterpret_cast<T*>(lua_ptr);

	if (remove) {
		lua_remove(L, stackposition);
	}

	return true;
}

}
}


#endif