Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bugfix rxcpp android #461

Merged
merged 2 commits into from
Nov 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions include/Application/RunLoop.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,12 @@
#include <rxcpp/operators/rx-observe_on.hpp>
#include <rxcpp/schedulers/rx-runloop.hpp>

#if defined(__ANDROID__)
#include <android/looper.h>
#endif

#include "Utility/Log.hpp"

namespace VGG
{

Expand All @@ -33,7 +39,15 @@ class RunLoop

rxcpp::observe_on_one_worker thread()
{
#if defined(__ANDROID__)
ALooper* looper = ALooper_forThread();
if (looper == nullptr) {
looper = ALooper_prepare(ALOOPER_PREPARE_ALLOW_NON_CALLBACKS);
}
return rxcpp::observe_on_new_thread();
#else
return rxcpp::observe_on_run_loop(m_runLoop);
#endif
}

bool empty() const
Expand Down
5 changes: 4 additions & 1 deletion include/Utility/VggTimer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,15 @@ class Timer
using TCallback = std::function<void()>;

private:
double m_interval;
TCallback m_callback;
bool m_repeats;
rxcpp::composite_subscription m_timer;

public:
Timer(double interval, TCallback callback, bool repeats = false);
bool setup();
void invalidate();
};

} // namespace VGG
} // namespace VGG
16 changes: 10 additions & 6 deletions src/Application/Controller.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1066,11 +1066,15 @@ LayoutContext* Controller::layoutContext()

void Controller::postFrame()
{
auto context = layoutContext();
context->setLayerValid(true);
currentFrame()->layoutIfNeeded(context); // layout text if needed
if (!context->isLayerValid()) // paint node updated
m_presenter->setDirtry();
if (auto context = layoutContext())
{
context->setLayerValid(true);
currentFrame()->layoutIfNeeded(context); // layout text if needed
if (!context->isLayerValid()) // paint node updated
{
m_presenter->setDirtry();
}
}
}

std::shared_ptr<LayoutNode> Controller::currentFrame()
Expand All @@ -1090,4 +1094,4 @@ Statistic* Controller::statistic()
return m_statistic.get();
}

} // namespace VGG
} // namespace VGG
27 changes: 22 additions & 5 deletions src/Application/Presenter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -285,7 +285,10 @@ bool Presenter::dismissFrame(app::AnimationCompletion completion)

void Presenter::initHistory()
{
return m_view->initHistory();
if (m_view)
{
m_view->initHistory();
}
}

bool Presenter::popFrame(const app::PopOptions& opts, app::AnimationCompletion completion)
Expand All @@ -302,8 +305,14 @@ std::shared_ptr<StateTree> Presenter::savedState(const std::string& instanceDesc

void Presenter::triggerMouseEnter()
{
ASSERT(m_view);
m_view->triggerMouseEnter();
if (m_view)
{
m_view->triggerMouseEnter();
}
else
{
WARN("Presenter::triggerMouseEnter: Invalid view");
}
}

void Presenter::fitForRunning(const Layout::Size& pageSize)
Expand Down Expand Up @@ -391,6 +400,10 @@ void Presenter::fitForAspectScale(const Layout::Size& pageSize)

bool Presenter::setCurrentFrameIndex(const std::size_t index, const bool updateHistory)
{
if (!m_view)
{
return false;
}
const auto success = m_view->setCurrentFrameIndex(index, updateHistory, {}, {});
if (success && updateHistory)
m_lastPushFrameAnimationOptions = {};
Expand Down Expand Up @@ -445,7 +458,11 @@ bool Presenter::presentInstanceState(

std::unique_ptr<LayoutContext> Presenter::layoutContext()
{
return m_view->layoutContext();
if (m_view)
{
return m_view->layoutContext();
}
return nullptr;
}

void Presenter::setBackgroundColor(uint32_t color)
Expand Down Expand Up @@ -476,4 +493,4 @@ bool Presenter::deleteElementProperty(const app::ElementDeleteProperty& command)
return m_view->deleteElementProperty(command);
}

} // namespace VGG
} // namespace VGG
7 changes: 6 additions & 1 deletion src/Application/Presenter.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,12 @@ class Presenter : public std::enable_shared_from_this<Presenter>

virtual int currentPageIndex()
{
return m_view->currentPageIndex();
if (m_view)
{
return m_view->currentPageIndex();
}
WARN("Invalid view");
return 0;
}
bool setCurrentFrameIndex(const std::size_t index, const bool updateHistory);
bool pushFrame(
Expand Down
9 changes: 7 additions & 2 deletions src/Application/UIScrollView.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -316,14 +316,19 @@ void UIScrollView::setScrollAnimation(std::shared_ptr<UIScrollViewAnimation> ani

if (!m_scrollTimer)
{
m_scrollTimer.reset(new Timer(
auto t = new Timer(
1. / 60,
[this]()
{
VERBOSE("UIScrollView: call updateScrollAnimation by timer");
this->updateScrollAnimation();
},
true));
true);
m_scrollTimer.reset(t);
if (!m_scrollTimer->setup())
{
WARN("Failed to setup scroll timer");
}
}
}

Expand Down
42 changes: 26 additions & 16 deletions src/Utility/VggTimer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,35 +37,45 @@ namespace VGG
{

Timer::Timer(double interval, TCallback callback, bool repeats)
: m_callback(callback)
: m_interval(interval)
, m_callback(callback)
, m_repeats(repeats)
{
auto period = std::chrono::milliseconds(static_cast<int64_t>(interval * 1000));
}

bool Timer::setup()
{
auto period = std::chrono::milliseconds(static_cast<int64_t>(m_interval * 1000));

if (repeats)
if (m_repeats)
{
auto values = rxcpp::observable<>::interval(period);
m_timer = values.observe_on(RunLoop::sharedInstance()->thread())
.subscribe([this](int v) { this->m_callback(); }, []() {});
auto observeTarget = RunLoop::sharedInstance()->thread();
auto s = values
#if defined(__ANDROID__)
.subscribe_on(rxcpp::observe_on_new_thread())
#endif
.observe_on(observeTarget);
m_timer = s.subscribe([this](int v) { if (this->m_callback) { this->m_callback(); } }, []() {});
}
else
{
auto values = rxcpp::observable<>::timer(period);
m_timer = values.observe_on(RunLoop::sharedInstance()->thread())
.subscribe(
[this](int v)
{
if (this->m_callback)
{
this->m_callback();
}
},
[]() {});
auto observeTarget = RunLoop::sharedInstance()->thread();
auto s = values
#if defined(__ANDROID__)
.subscribe_on(rxcpp::observe_on_new_thread())
#endif
.observe_on(observeTarget);
m_timer = s.subscribe([this](int v) { if (this->m_callback) { this->m_callback(); } }, []() {});
}

return true;
}

void Timer::invalidate()
{
m_timer.unsubscribe();
}

} // namespace VGG
} // namespace VGG
Loading