1// Aseprite
2// Copyright (C) 2018 Igara Studio S.A.
3// Copyright (C) 2018 David Capello
4//
5// This program is distributed under the terms of
6// the End-User License Agreement for Aseprite.
7
8#ifdef HAVE_CONFIG_H
9#include "config.h"
10#endif
11
12#include "app/script/docobj.h"
13#include "app/script/engine.h"
14#include "app/script/luacpp.h"
15#include "doc/sprite.h"
16
17namespace app {
18namespace script {
19
20using namespace doc;
21
22namespace {
23
24struct FramesObj {
25 ObjectId spriteId;
26 const std::vector<frame_t>* frames;
27
28 FramesObj(Sprite* sprite)
29 : spriteId(sprite->id()),
30 frames(nullptr) {
31 }
32 FramesObj(Sprite* sprite, const std::vector<frame_t>& frames)
33 : spriteId(sprite->id()),
34 frames(new std::vector<frame_t>(frames)) {
35 }
36
37 ~FramesObj() {
38 delete frames;
39 }
40
41 FramesObj(const FramesObj&) = delete;
42 FramesObj& operator=(const FramesObj&) = delete;
43
44 Sprite* sprite(lua_State* L) { return check_docobj(L, doc::get<Sprite>(spriteId)); }
45};
46
47int Frames_gc(lua_State* L)
48{
49 get_obj<FramesObj>(L, 1)->~FramesObj();
50 return 0;
51}
52
53int Frames_len(lua_State* L)
54{
55 auto obj = get_obj<FramesObj>(L, 1);
56 if (obj->frames)
57 lua_pushinteger(L, int(obj->frames->size()));
58 else
59 lua_pushinteger(L, obj->sprite(L)->totalFrames());
60 return 1;
61}
62
63int Frames_index(lua_State* L)
64{
65 auto obj = get_obj<FramesObj>(L, 1);
66 auto sprite = obj->sprite(L);
67 int i = lua_tonumber(L, 2);
68
69 if (obj->frames) {
70 if (i >= 1 && i <= obj->frames->size())
71 i = (*obj->frames)[i-1]+1;
72 else
73 i = 0;
74 }
75
76 if (i >= 1 && i <= sprite->totalFrames())
77 push_sprite_frame(L, sprite, i-1);
78 else
79 lua_pushnil(L);
80 return 1;
81}
82
83const luaL_Reg Frames_methods[] = {
84 { "__gc", Frames_gc },
85 { "__len", Frames_len },
86 { "__index", Frames_index },
87 { nullptr, nullptr }
88};
89
90} // anonymous namespace
91
92DEF_MTNAME(FramesObj);
93
94void register_frames_class(lua_State* L)
95{
96 using Frames = FramesObj;
97 REG_CLASS(L, Frames);
98}
99
100void push_sprite_frames(lua_State* L, Sprite* sprite)
101{
102 push_new<FramesObj>(L, sprite);
103}
104
105void push_sprite_frames(lua_State* L, doc::Sprite* sprite, const std::vector<doc::frame_t>& frames)
106{
107 push_new<FramesObj>(L, sprite, frames);
108}
109
110} // namespace script
111} // namespace app
112