Skip to content

Commit b9130b8

Browse files
committed
Merge branch 'interprocessing'
2 parents bcb05d9 + 6e84bb5 commit b9130b8

28 files changed

+749
-58
lines changed

.gitmodules

+3
Original file line numberDiff line numberDiff line change
@@ -69,3 +69,6 @@
6969
[submodule "third_party/curl"]
7070
path = third_party/curl
7171
url = https://github.com/aseprite/curl.git
72+
[submodule "third_party/IXWebSocket"]
73+
path = third_party/IXWebSocket
74+
url = https://github.com/machinezone/IXWebSocket

CMakeLists.txt

+1
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ option(ENABLE_MEMLEAK "Enable memory-leaks detector (only for developers)"
7070
option(ENABLE_NEWS "Enable the news in Home tab" on)
7171
option(ENABLE_UPDATER "Enable automatic check for updates" on)
7272
option(ENABLE_SCRIPTING "Compile with scripting support" on)
73+
option(ENABLE_WEBSOCKET "Compile with websocket support" on)
7374
option(ENABLE_TESTS "Compile unit tests" off)
7475
option(ENABLE_BENCHMARKS "Compile benchmarks" off)
7576
option(ENABLE_TRIAL_MODE "Compile the trial version" off)

data/strings/en.ini

+2
Original file line numberDiff line numberDiff line change
@@ -1377,11 +1377,13 @@ title = Security
13771377
script_label = The following script:
13781378
file_label = wants to access to this file:
13791379
command_label = wants to execute the following command:
1380+
websocket_label = wants to open a WebSocket connection to this URL:
13801381
dont_show_for_this_access = Don't show this specific alert again for this script
13811382
dont_show_for_this_script = Give full trust to this script
13821383
allow_execute_access = &Allow Execute Access
13831384
allow_write_access = &Allow Write Access
13841385
allow_read_access = &Allow Read Access
1386+
allow_open_conn_access = &Allow to Open Connections
13851387
give_full_access = Give Script Full &Access
13861388
stop_script = &Stop Script
13871389

laf

src/CMakeLists.txt

+5
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,11 @@ if(ENABLE_SCRIPTING)
7474
add_definitions(-DENABLE_SCRIPTING)
7575
endif()
7676

77+
if(ENABLE_WEBSOCKET)
78+
# Needed for "app" and "main"
79+
add_definitions(-DENABLE_WEBSOCKET)
80+
endif()
81+
7782
######################################################################
7883
# Aseprite Libraries (in preferred order to be built)
7984

src/app/CMakeLists.txt

+10
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,10 @@ if(ENABLE_SCRIPTING)
147147
commands/cmd_open_script_folder.cpp
148148
ui/devconsole_view.cpp)
149149
endif()
150+
if(ENABLE_WEBSOCKET)
151+
set(scripting_files_ws
152+
script/websocket_class.cpp)
153+
endif()
150154
set(scripting_files
151155
commands/cmd_run_script.cpp
152156
script/app_command_object.cpp
@@ -159,6 +163,7 @@ if(ENABLE_SCRIPTING)
159163
script/color_space_class.cpp
160164
script/dialog_class.cpp
161165
script/engine.cpp
166+
script/events_class.cpp
162167
script/frame_class.cpp
163168
script/frames_class.cpp
164169
script/image_class.cpp
@@ -190,6 +195,7 @@ if(ENABLE_SCRIPTING)
190195
script/values.cpp
191196
script/version_class.cpp
192197
shell.cpp
198+
${scripting_files_ws}
193199
${scripting_files_ui})
194200
endif()
195201

@@ -674,6 +680,10 @@ endif()
674680

675681
if(ENABLE_SCRIPTING)
676682
target_link_libraries(app-lib lua lauxlib lualib)
683+
684+
if(ENABLE_WEBSOCKET)
685+
target_link_libraries(app-lib ixwebsocket)
686+
endif()
677687
endif()
678688

679689
if(ENABLE_UPDATER)

src/app/active_site_handler.cpp

+6-5
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// Aseprite
2-
// Copyright (C) 2019-2020 Igara Studio S.A.
2+
// Copyright (C) 2019-2021 Igara Studio S.A.
33
//
44
// This program is distributed under the terms of
55
// the End-User License Agreement for Aseprite.
@@ -28,10 +28,11 @@ ActiveSiteHandler::~ActiveSiteHandler()
2828
void ActiveSiteHandler::addDoc(Doc* doc)
2929
{
3030
Data data;
31-
if (doc::Layer* layer = doc->sprite()->root()->firstLayer())
32-
data.layer = layer->id();
33-
else
34-
data.layer = doc::NullId;
31+
data.layer = doc::NullId;
32+
if (doc->sprite()) { // The sprite can be nullptr in some tests
33+
if (doc::Layer* layer = doc->sprite()->root()->firstLayer())
34+
data.layer = layer->id();
35+
}
3536
data.frame = 0;
3637
m_data.insert(std::make_pair(doc, data));
3738
doc->add_observer(this);

src/app/context.cpp

+21-8
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// Aseprite
2-
// Copyright (C) 2018-2020 Igara Studio S.A.
2+
// Copyright (C) 2018-2021 Igara Studio S.A.
33
// Copyright (C) 2001-2018 David Capello
44
//
55
// This program is distributed under the terms of
@@ -81,7 +81,7 @@ Doc* Context::activeDocument() const
8181

8282
void Context::setActiveDocument(Doc* document)
8383
{
84-
onSetActiveDocument(document);
84+
onSetActiveDocument(document, true);
8585
}
8686

8787
void Context::setActiveLayer(doc::Layer* layer)
@@ -206,15 +206,19 @@ void Context::onAddDocument(Doc* doc)
206206

207207
if (m_activeSiteHandler)
208208
m_activeSiteHandler->addDoc(doc);
209+
210+
notifyActiveSiteChanged();
209211
}
210212

211213
void Context::onRemoveDocument(Doc* doc)
212214
{
213-
if (doc == m_lastSelectedDoc)
214-
m_lastSelectedDoc = nullptr;
215-
216215
if (m_activeSiteHandler)
217216
m_activeSiteHandler->removeDoc(doc);
217+
218+
if (doc == m_lastSelectedDoc) {
219+
m_lastSelectedDoc = nullptr;
220+
notifyActiveSiteChanged();
221+
}
218222
}
219223

220224
void Context::onGetActiveSite(Site* site) const
@@ -224,24 +228,33 @@ void Context::onGetActiveSite(Site* site) const
224228
activeSiteHandler()->getActiveSiteForDoc(doc, site);
225229
}
226230

227-
void Context::onSetActiveDocument(Doc* doc)
231+
void Context::onSetActiveDocument(Doc* doc, bool notify)
228232
{
229233
m_lastSelectedDoc = doc;
234+
if (notify)
235+
notifyActiveSiteChanged();
230236
}
231237

232238
void Context::onSetActiveLayer(doc::Layer* layer)
233239
{
234240
Doc* newDoc = (layer ? static_cast<Doc*>(layer->sprite()->document()): nullptr);
241+
if (!newDoc)
242+
return;
243+
244+
activeSiteHandler()->setActiveLayerInDoc(newDoc, layer);
245+
235246
if (newDoc != m_lastSelectedDoc)
236247
setActiveDocument(newDoc);
237-
if (newDoc)
238-
activeSiteHandler()->setActiveLayerInDoc(newDoc, layer);
248+
else
249+
notifyActiveSiteChanged();
239250
}
240251

241252
void Context::onSetActiveFrame(const doc::frame_t frame)
242253
{
243254
if (m_lastSelectedDoc)
244255
activeSiteHandler()->setActiveFrameInDoc(m_lastSelectedDoc, frame);
256+
257+
notifyActiveSiteChanged();
245258
}
246259

247260
void Context::onSetRange(const DocRange& range)

src/app/context.h

+5-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// Aseprite
2-
// Copyright (C) 2018-2020 Igara Studio S.A.
2+
// Copyright (C) 2018-2021 Igara Studio S.A.
33
// Copyright (C) 2001-2018 David Capello
44
//
55
// This program is distributed under the terms of
@@ -110,7 +110,7 @@ namespace app {
110110
void onRemoveDocument(Doc* doc) override;
111111

112112
virtual void onGetActiveSite(Site* site) const;
113-
virtual void onSetActiveDocument(Doc* doc);
113+
virtual void onSetActiveDocument(Doc* doc, bool notify);
114114
virtual void onSetActiveLayer(doc::Layer* layer);
115115
virtual void onSetActiveFrame(const doc::frame_t frame);
116116
virtual void onSetRange(const DocRange& range);
@@ -122,10 +122,12 @@ namespace app {
122122
private:
123123
ActiveSiteHandler* activeSiteHandler() const;
124124

125+
// This must be defined before m_docs because ActiveSiteHandler
126+
// will be an observer of all documents.
127+
mutable std::unique_ptr<ActiveSiteHandler> m_activeSiteHandler;
125128
mutable Docs m_docs;
126129
ContextFlags m_flags; // Last updated flags.
127130
Doc* m_lastSelectedDoc;
128-
mutable std::unique_ptr<ActiveSiteHandler> m_activeSiteHandler;
129131
mutable std::unique_ptr<Preferences> m_preferences;
130132

131133
DISABLE_COPYING(Context);

src/app/doc.cpp

+8
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,14 @@ Doc::Doc(Sprite* sprite)
7070
Doc::~Doc()
7171
{
7272
DOC_TRACE("DOC: Deleting", this);
73+
74+
try {
75+
notify_observers<Doc*>(&DocObserver::onDestroy, this);
76+
}
77+
catch (...) {
78+
LOG(ERROR, "DOC: Exception on DocObserver::onDestroy()\n");
79+
}
80+
7381
removeFromContext();
7482
}
7583

src/app/doc_observer.h

+1-2
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ namespace app {
1717
public:
1818
virtual ~DocObserver() { }
1919

20+
virtual void onDestroy(Doc* doc) { }
2021
virtual void onFileNameChanged(Doc* doc) { }
2122

2223
// General update. If an observer receives this event, it's because
@@ -80,8 +81,6 @@ namespace app {
8081
// Slices
8182
virtual void onSliceNameChange(DocEvent& ev) { }
8283

83-
// Called to destroy the observable. (Here you could call "delete this".)
84-
virtual void dispose() { }
8584
};
8685

8786
} // namespace app

src/app/doc_undo_observer.h

+6-5
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
// Aseprite
2+
// Copyright (C) 2021 Igara Studio S.A.
23
// Copyright (C) 2015-2018 David Capello
34
//
45
// This program is distributed under the terms of
@@ -19,12 +20,12 @@ namespace app {
1920
class DocUndoObserver {
2021
public:
2122
virtual ~DocUndoObserver() { }
22-
virtual void onAddUndoState(DocUndo* history) = 0;
23+
virtual void onAddUndoState(DocUndo* history) { }
2324
virtual void onDeleteUndoState(DocUndo* history,
24-
undo::UndoState* state) = 0;
25-
virtual void onCurrentUndoStateChange(DocUndo* history) = 0;
26-
virtual void onClearRedo(DocUndo* history) = 0;
27-
virtual void onTotalUndoSizeChange(DocUndo* history) = 0;
25+
undo::UndoState* state) { }
26+
virtual void onCurrentUndoStateChange(DocUndo* history) { }
27+
virtual void onClearRedo(DocUndo* history) { }
28+
virtual void onTotalUndoSizeChange(DocUndo* history) { }
2829
};
2930

3031
} // namespace app

src/app/script/app_fs_object.cpp

+3-3
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ int AppFS_makeDirectory(lua_State* L)
126126
return 1;
127127
}
128128

129-
if (!ask_access(L, path, FileAccessMode::Write, true))
129+
if (!ask_access(L, path, FileAccessMode::Full, ResourceType::File))
130130
return luaL_error(L, "the script doesn't have access to create the directory '%s'", path);
131131

132132
try {
@@ -148,7 +148,7 @@ int AppFS_makeAllDirectories(lua_State* L)
148148
return 1;
149149
}
150150

151-
if (!ask_access(L, path, FileAccessMode::Write, true))
151+
if (!ask_access(L, path, FileAccessMode::Write, ResourceType::File))
152152
return luaL_error(L, "the script doesn't have access to create all directories '%s'", path);
153153

154154
try {
@@ -170,7 +170,7 @@ int AppFS_removeDirectory(lua_State* L)
170170
return 1;
171171
}
172172

173-
if (!ask_access(L, path, FileAccessMode::Write, true))
173+
if (!ask_access(L, path, FileAccessMode::Write, ResourceType::File))
174174
return luaL_error(L, "the script doesn't have access to remove the directory '%s'", path);
175175

176176
try {

src/app/script/app_object.cpp

+8-1
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ int load_sprite_from_file(lua_State* L, const char* filename,
5858
const LoadSpriteFromFileParam param)
5959
{
6060
std::string absFn = base::get_absolute_path(filename);
61-
if (!ask_access(L, absFn.c_str(), FileAccessMode::Read, true))
61+
if (!ask_access(L, absFn.c_str(), FileAccessMode::Read, ResourceType::File))
6262
return luaL_error(L, "script doesn't have access to open file %s",
6363
absFn.c_str());
6464

@@ -456,6 +456,12 @@ int App_useTool(lua_State* L)
456456
return 0;
457457
}
458458

459+
int App_get_events(lua_State* L)
460+
{
461+
push_app_events(L);
462+
return 1;
463+
}
464+
459465
int App_get_activeSprite(lua_State* L)
460466
{
461467
app::Context* ctx = App::instance()->context();
@@ -736,6 +742,7 @@ const Property App_properties[] = {
736742
{ "range", App_get_range, nullptr },
737743
{ "isUIAvailable", App_get_isUIAvailable, nullptr },
738744
{ "defaultPalette", App_get_defaultPalette, App_set_defaultPalette },
745+
{ "events", App_get_events, nullptr },
739746
{ nullptr, nullptr, nullptr }
740747
};
741748

src/app/script/engine.cpp

+6
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,7 @@ void register_color_space_class(lua_State* L);
155155
#ifdef ENABLE_UI
156156
void register_dialog_class(lua_State* L);
157157
#endif
158+
void register_events_class(lua_State* L);
158159
void register_frame_class(lua_State* L);
159160
void register_frames_class(lua_State* L);
160161
void register_image_class(lua_State* L);
@@ -180,6 +181,7 @@ void register_tag_class(lua_State* L);
180181
void register_tags_class(lua_State* L);
181182
void register_tool_class(lua_State* L);
182183
void register_version_class(lua_State* L);
184+
void register_websocket_class(lua_State* L);
183185

184186
void set_app_params(lua_State* L, const Params& params);
185187

@@ -386,6 +388,7 @@ Engine::Engine()
386388
#ifdef ENABLE_UI
387389
register_dialog_class(L);
388390
#endif
391+
register_events_class(L);
389392
register_frame_class(L);
390393
register_frames_class(L);
391394
register_image_class(L);
@@ -411,6 +414,9 @@ Engine::Engine()
411414
register_tags_class(L);
412415
register_tool_class(L);
413416
register_version_class(L);
417+
#if ENABLE_WEBSOCKET
418+
register_websocket_class(L);
419+
#endif
414420

415421
// Check that we have a clean start (without dirty in the stack)
416422
ASSERT(lua_gettop(L) == top);

src/app/script/engine.h

+3-8
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// Aseprite
2-
// Copyright (C) 2018-2020 Igara Studio S.A.
2+
// Copyright (C) 2018-2021 Igara Studio S.A.
33
// Copyright (C) 2001-2018 David Capello
44
//
55
// This program is distributed under the terms of
@@ -58,13 +58,6 @@ namespace app {
5858

5959
namespace script {
6060

61-
enum class FileAccessMode {
62-
Execute = 1,
63-
Write = 2,
64-
Read = 4,
65-
Full = 7
66-
};
67-
6861
class EngineDelegate {
6962
public:
7063
virtual ~EngineDelegate() { }
@@ -121,6 +114,7 @@ namespace app {
121114
EngineDelegate* m_oldDelegate;
122115
};
123116

117+
void push_app_events(lua_State* L);
124118
int push_image_iterator_function(lua_State* L, const doc::Image* image, int extraArgIndex);
125119
void push_brush(lua_State* L, const doc::BrushRef& brush);
126120
void push_cel_image(lua_State* L, doc::Cel* cel);
@@ -136,6 +130,7 @@ namespace app {
136130
void push_palette(lua_State* L, doc::Palette* palette);
137131
void push_plugin(lua_State* L, Extension* ext);
138132
void push_sprite_cel(lua_State* L, doc::Cel* cel);
133+
void push_sprite_events(lua_State* L, doc::Sprite* sprite);
139134
void push_sprite_frame(lua_State* L, doc::Sprite* sprite, doc::frame_t frame);
140135
void push_sprite_frames(lua_State* L, doc::Sprite* sprite);
141136
void push_sprite_frames(lua_State* L, doc::Sprite* sprite, const std::vector<doc::frame_t>& frames);

0 commit comments

Comments
 (0)