58 if (!env || !adapter)
return;
59 auto& state = *state_;
60 state.vm = detail::vm_of(env);
61 if (!state.vm)
return;
62 state.adapter = env->NewGlobalRef(adapter);
63 if (detail::check_exception(env,
"NewGlobalRef") || !state.adapter)
return;
64 state.inserted = detail::method(env, state.adapter,
"notifyItemInserted",
"(I)V");
65 if (!state.inserted)
return;
66 state.removed = detail::method(env, state.adapter,
"notifyItemRemoved",
"(I)V");
67 if (!state.removed)
return;
68 state.changed = detail::method(env, state.adapter,
"notifyItemChanged",
"(I)V");
69 if (!state.changed)
return;
70 state.moved = detail::method(env, state.adapter,
"notifyItemMoved",
"(II)V");
71 if (!state.moved)
return;
72 state.dataset = detail::method(env, state.adapter,
"notifyDataSetChanged",
"()V");
73 state.active.store(state.dataset !=
nullptr, std::memory_order_release);
80 [[nodiscard]]
bool valid() const noexcept {
81 return state_->active.load(std::memory_order_acquire);
88 if (
auto state = weak.lock()) dispatch_(state, notification);
97 jobject adapter =
nullptr;
98 jmethodID inserted =
nullptr, removed =
nullptr, changed =
nullptr;
99 jmethodID moved =
nullptr, dataset =
nullptr;
100 std::atomic<bool> active{
false};
101 ~State() { detail::delete_global_ref(vm, adapter); }
104 static void dispatch_(std::shared_ptr<State> state,
const RecyclerNotification& n) {
105 if (!state->active.load(std::memory_order_acquire))
return;
106 constexpr auto maximum =
static_cast<std::size_t
>(std::numeric_limits<jint>::max());
112 detail::Env scope(state->vm);
113 auto* env = scope.get();
114 if (!env || detail::check_exception(env,
"RecyclerView notification"))
return;
115 if (!state->active.load(std::memory_order_acquire))
return;
118 env->CallVoidMethod(state->adapter, state->inserted,
static_cast<jint
>(n.position));
break;
120 env->CallVoidMethod(state->adapter, state->removed,
static_cast<jint
>(n.position));
break;
122 env->CallVoidMethod(state->adapter, state->changed,
static_cast<jint
>(n.position));
break;
124 env->CallVoidMethod(state->adapter, state->moved,
static_cast<jint
>(n.from_position),
static_cast<jint
>(n.position));
break;
126 env->CallVoidMethod(state->adapter, state->dataset);
break;
128 detail::check_exception(env,
"RecyclerView notification");
131 std::shared_ptr<State> state_;
void report_callback_failure(std::string_view category, std::exception_ptr exception, std::string_view message={}) noexcept
Report a callback failure.