1// Aseprite
2// Copyright (C) 2018 Igara Studio S.A.
3//
4// This program is distributed under the terms of
5// the End-User License Agreement for Aseprite.
6
7#ifndef APP_SCRIPT_DOCOBJ_H_INCLUDED
8#define APP_SCRIPT_DOCOBJ_H_INCLUDED
9#pragma once
10
11#include "app/script/luacpp.h"
12#include "doc/object.h"
13
14namespace app {
15namespace script {
16
17// Functions to push/get doc:: objects from Lua stack with doc::ObjectId.
18// This can be used to avoid crashes accesing raw pointers.
19
20template <typename T> void push_docobj(lua_State* L, doc::ObjectId id) {
21 new (lua_newuserdata(L, sizeof(doc::ObjectId))) doc::ObjectId(id);
22 luaL_getmetatable(L, get_mtname<T>());
23 lua_setmetatable(L, -2);
24}
25
26template <typename T> void push_docobj(lua_State* L, T* obj) {
27 push_docobj<T>(L, obj->id());
28}
29
30template <typename T> T* may_get_docobj(lua_State* L, int index) {
31 const doc::ObjectId* id = (doc::ObjectId*)luaL_testudata(L, index, get_mtname<T>());
32 if (id) {
33 T* obj = doc::get<T>(*id);
34 if (obj)
35 return obj;
36 }
37 return nullptr;
38}
39
40template <typename T> T* check_docobj(lua_State* L, T* obj) {
41 if (obj)
42 return obj;
43 else {
44 luaL_error(L, "Using a nil '%s' object", get_mtname<T>());
45 ASSERT(false); // unreachable code
46 return nullptr;
47 }
48}
49
50template <typename T> T* get_docobj(lua_State* L, int index) {
51 return check_docobj<T>(L, may_get_docobj<T>(L, index));
52}
53
54} // namespace script
55} // namespace app
56
57#endif
58