diff --git a/android/src/main/cpp/main.cpp b/android/src/main/cpp/main.cpp index 3640b03..7428cc5 100755 --- a/android/src/main/cpp/main.cpp +++ b/android/src/main/cpp/main.cpp @@ -357,6 +357,7 @@ static void engine_term_display(struct engine* engine) { engine->display = EGL_NO_DISPLAY; engine->context = EGL_NO_CONTEXT; engine->surface = EGL_NO_SURFACE; + App::I.terminate(); } /** @@ -528,7 +529,7 @@ static void engine_handle_cmd(struct android_app* app, int32_t cmd) { case APP_CMD_TERM_WINDOW: // The window is being hidden or closed, clean it up. engine_term_display(engine); - exit(0); + //exit(0); break; case APP_CMD_GAINED_FOCUS: // When our app gains focus, we start monitoring the accelerometer. diff --git a/engine/app.cpp b/engine/app.cpp index 87ccee0..d87804d 100644 --- a/engine/app.cpp +++ b/engine/app.cpp @@ -499,18 +499,16 @@ void App::initLayout() } }; LOG("initializing layout xml"); -#ifdef _WIN32 - //layout.load("C:\\Users\\omar\\Desktop\\new_engine\\data\\layout.xml"); - layout.load("data/layout.xml"); -#else - layout.load("data/layout.xml"); -#endif + if (layout.m_loaded) + layout[main_id]->restore_context(); + else + layout.load("data/layout.xml"); LOG("initializing layout completed"); } void App::initLog() { - LogRemote::I.start(); + //LogRemote::I.start(); } void App::init() { @@ -721,3 +719,8 @@ bool App::key_char(char key) layout[main_id]->update(); return ret == kEventResult::Consumed; } + +void App::terminate() +{ + TextureManager::invalidate(); +} diff --git a/engine/app.h b/engine/app.h index 34b6182..2a03ffd 100644 --- a/engine/app.h +++ b/engine/app.h @@ -47,6 +47,7 @@ public: void initAssets(); void initLayout(); void create(); + void terminate(); void clear(); void update(float dt); void resize(float w, float h); diff --git a/engine/canvas.cpp b/engine/canvas.cpp index a0574c7..a5d17ba 100644 --- a/engine/canvas.cpp +++ b/engine/canvas.cpp @@ -364,3 +364,13 @@ bool ui::Canvas::create(int width, int height) m_mesh.create(); return true; } + +void ui::Canvas::snapshot_save() +{ + +} + +void ui::Canvas::snapshot_restore() +{ + +}; \ No newline at end of file diff --git a/engine/canvas.h b/engine/canvas.h index 52f3664..97811c0 100644 --- a/engine/canvas.h +++ b/engine/canvas.h @@ -16,6 +16,10 @@ public: bool m_locked = false; float m_opacity = 1.f; std::string m_name; + struct Snapshot + { + std::unique_ptr image[6]; + }; bool create(int width, int height, std::string name) { for (int i = 0; i < 6; i++) @@ -44,6 +48,16 @@ public: // restore clear color state glClearColor(cc[0], cc[1], cc[2], cc[3]); } + Snapshot snapshot() + { + Snapshot snap; + for (int i = 0; i < 6; i++) + { + snap.image[i] = std::make_unique(m_rtt[i].bytes()); + m_rtt[i].readTextureData(snap.image[i].get()); + } + return snap; + } }; class Canvas @@ -78,6 +92,8 @@ public: Sampler m_sampler_bg; glm::vec2 m_cam_rot; float m_cam_fov = 85; + + std::vector m_layers_snapshot; bool create(int width, int height); void resize(int width, int height); @@ -89,6 +105,8 @@ public: void stroke_end(); void stroke_commit(); void clear(const glm::vec4& color = { 1, 1, 1, 1 }); + void snapshot_save(); + void snapshot_restore(); }; diff --git a/engine/layout.cpp b/engine/layout.cpp index 8b0a37b..9bb13cf 100644 --- a/engine/layout.cpp +++ b/engine/layout.cpp @@ -534,6 +534,9 @@ void Node::clone_children(Node* dest) const bool LayoutManager::load(const char* path) { + if (m_loaded) + return true; // already loaded + #ifndef __ANDROID__ struct stat tmp_info; if (stat(path, &tmp_info) != 0) @@ -598,6 +601,7 @@ bool LayoutManager::load(const char* path) } if (on_loaded) on_loaded(); + m_loaded = true; return true; } diff --git a/engine/layout.h b/engine/layout.h index ecc37fd..0b150f8 100644 --- a/engine/layout.h +++ b/engine/layout.h @@ -92,6 +92,7 @@ class LayoutManager std::string m_path; struct stat m_file_info { 0 }; public: + bool m_loaded = false; std::function on_loaded; bool load(const char* path); bool reload(); @@ -218,6 +219,13 @@ public: return o; } + virtual void restore_context() + { + for (auto& c : m_children) + { + c->restore_context(); + } + }; void update(float width, float height, float zoom); void update(); void update_internal(const glm::vec2& origin, const glm::mat4& proj); @@ -275,39 +283,6 @@ public: void mouse_release() { root()->current_mouse_capture = nullptr; m_mouse_captured = false; } void key_capture() { root()->current_key_capture = this; m_key_captured = true; } void key_release() { root()->current_key_capture = nullptr; m_key_captured = false; } - -// class iterator -// { -// std::stack m_nodes; -// Node* m_current; -// public: -// iterator(Node* root) -// { -// m_current = root; -// if (root) -// m_nodes.push(root); -// } -// iterator& operator++() -// { -// m_nodes.pop(); -// for (auto& c : m_current->m_children) -// m_nodes.push(c.get()); -// m_current = m_nodes.size() ? m_nodes.top() : nullptr; -// return *this; -// } -// Node& operator*() { return *m_current; } -// Node* operator->() { return m_current; } -// bool operator==(const iterator& rhs) { return m_current == rhs.m_current; } -// bool operator!=(const iterator& rhs) { return m_current != rhs.m_current; } -// }; -// iterator begin() -// { -// return this; -// } -// iterator end() -// { -// return nullptr; -// } }; class NodeBorder : public Node @@ -421,6 +396,11 @@ public: m_text_mesh.update(font_id, m_text.c_str()); SetSize(m_text_mesh.bb); } + virtual void restore_context() override + { + Node::restore_context(); + create(); + } virtual void parse_attributes(kAttribute ka, const tinyxml2::XMLAttribute* attr) override { Node::parse_attributes(ka, attr); @@ -507,6 +487,11 @@ public: m_sz = (m_region.zw - m_region.xy) / tex_sz; } } + virtual void restore_context() override + { + Node::restore_context(); + create(); + } virtual void parse_attributes(kAttribute ka, const tinyxml2::XMLAttribute* attr) override { Node::parse_attributes(ka, attr); @@ -1711,6 +1696,12 @@ public: TextureManager::load("data/Icons/Round-Hard.png"); m_brush.m_tex_id = const_hash("data/Icons/Round-Hard.png"); } + virtual void restore_context() override + { + NodeBorder::restore_context(); + init_controls(); + m_rtt.create(m_rtt.getWidth(), m_rtt.getHeight()); + } void draw_stroke() { m_rtt.bindFramebuffer(); @@ -1880,6 +1871,13 @@ public: m_sampler.create(); m_face_plane.create<1>(2, 2); } + virtual void restore_context() override + { + Node::restore_context(); + m_canvas->create(512, 512); + m_sampler.create(); + m_face_plane.create<1>(2, 2); + } virtual void draw() override { using namespace ui; diff --git a/engine/log.cpp b/engine/log.cpp index 3cb7644..57942ec 100644 --- a/engine/log.cpp +++ b/engine/log.cpp @@ -12,6 +12,9 @@ static size_t data_handler(void *contents, size_t size, size_t nmemb, void *user void LogRemote::start() { + if (m_running) + return; // already running + m_running = true; m_thread = std::thread([&] { net_init(); diff --git a/engine/rtt.cpp b/engine/rtt.cpp index 6d5273a..18ed8bb 100644 --- a/engine/rtt.cpp +++ b/engine/rtt.cpp @@ -144,7 +144,7 @@ void RTT::readTextureData(uint8_t* buffer) uint8_t* RTT::createBuffer() { - return new uint8_t[w * h * 3]; + return new uint8_t[w * h * 4]; } void RTT::bindTexture() diff --git a/engine/rtt.h b/engine/rtt.h index b1bb34e..9d9a869 100644 --- a/engine/rtt.h +++ b/engine/rtt.h @@ -26,5 +26,6 @@ public: GLuint getTextureID() { return texID; } int getWidth() { return w; } int getHeight() { return h; } + int bytes() { return w * h * 4; } GLuint getFBO() { return fboID; } }; diff --git a/engine/texture.cpp b/engine/texture.cpp index 36ccf3b..ba5e6df 100644 --- a/engine/texture.cpp +++ b/engine/texture.cpp @@ -25,6 +25,11 @@ Texture2D& TextureManager::get(uint16_t id) return m_textures[id]; } +void TextureManager::invalidate() +{ + m_textures.clear(); +} + bool Texture2D::create(int width, int height, GLint internal_format, GLint format, const uint8_t* data) { m_width = width; diff --git a/engine/texture.h b/engine/texture.h index e60ac59..df789cc 100644 --- a/engine/texture.h +++ b/engine/texture.h @@ -40,4 +40,5 @@ public: static bool load(const char* path); static void assign(uint16_t id, GLuint tex, int w = -1, int h = -1, GLuint internal_format = GL_RGBA8, GLuint format = GL_RGBA); static Texture2D& get(uint16_t id); + static void invalidate(); };