18GadgetImpl::~GadgetImpl()
22GadgetImpl::gadget_flags (uint64_t setbits, uint64_t mask)
24 gadget_flags_ &= mask;
25 gadget_flags_ |= setbits;
40GadgetImpl::fallback_name ()
const
46GadgetImpl::canonify_key (
const String &input)
48 String key = string_canonify (input, string_set_a2z() + string_set_A2Z() +
"_0123456789.",
"_");
49 if (key.size() && key[0] ==
'.')
55GadgetImpl::get_data (
const String &key)
const
57 const String ckey = canonify_key (key);
58 return session_data_[ckey];
64 const String ckey = canonify_key (key);
66 session_data_[ckey] = v;
67 emit_event (
"data", ckey);
75 String current_name = name();
76 if (xs.
in_save() && current_name != fallback_name())
77 xs[
"name"] & current_name;
78 if (xs.
in_load() && xs.has (
"name"))
81 xs[
"name"] & new_name;
82 if (current_name != new_name)
86 Serializable::serialize (xs);
88 for (PropertyP p : access_properties())
90 const String hints = p->hints();
95 Value v = p->get_value();
110 if (f.name[0] !=
'_' && f.value)
111 cdata[f.name] = *f.value;
113 xs[
"custom_data"] & cdata;
118 xs[
"custom_data"] & cdata;
121 set_data (f.name, *f.value);
126GadgetImpl::type_nick ()
const
128 String tname = Jsonipc::rtti_typename (*
this);
130 if (colon != ssize_t (tname.npos))
131 tname = tname.
substr (colon + 1);
132 if (string_endswith (tname,
"Impl"))
137static CustomDataKey<String> gadget_name_key;
140GadgetImpl::get_name ()
const
142 if (!has_custom_data (&gadget_name_key))
143 return fallback_name();
144 return get_custom_data (&gadget_name_key);
152 del_custom_data (&gadget_name_key);
154 set_custom_data (&gadget_name_key, newname);
159GadgetImpl::access_properties ()
163 return { begin (props_), end (props_) };
168Gadget::_project()
const
177Gadget::list_properties ()
179 PropertyS props = access_properties();
182 for (
const PropertyP &prop : props)
190 for (
const auto &p : access_properties())
191 if (p->ident() == ident)
199 PropertyP prop = access_property (ident);
200 return prop ? prop->get_value() :
Value {};
206 PropertyP prop = access_property (ident);
207 return prop && prop->set_value (v);
211 const char *member_typeid_name =
nullptr;
212 ptrdiff_t memb_offset = -1;
214 GadgetImpl::MemberInfosP infosp =
nullptr;
221 const char *class_typeid_name =
nullptr;
223 GadgetImpl::MemberClassT classtest =
nullptr;
231 return fnv1a_consthash64 (m.class_typeid_name);
233 static auto gcml_equal = [] (
const GadgetClassMemberList &a,
const GadgetClassMemberList &b) {
234 return !
strcmp (a.class_typeid_name, b.class_typeid_name);
236 using MemberAccessorSet =
std::unordered_set<GadgetClassMemberList,
decltype (gcml_hash),
decltype (gcml_equal)>;
237 static MemberAccessorSet mas (0, gcml_hash, gcml_equal);
242GadgetImpl::requires_accessor (
const char *ot,
const char *mt, ptrdiff_t offset)
244 auto &cml = cml_set();
245 const GadgetClassMemberList key { .class_typeid_name = ot };
246 auto it = cml.
find (key);
248 for (
const MemberAccessor *maf : it->members)
249 if (!
strcmp (mt, maf->member_typeid_name)) {
257GadgetImpl::register_accessor (
const char *ot,
const char *mt, ptrdiff_t offset, MemberClassT classtest,
258 const Param::ExtraVals &ev, MemberAccessF &&accessfunc,
259 MemberInfosP infosp, uint64_t flags)
261 auto &cml = cml_set();
262 auto [celement, inserted] = cml.emplace (ot, classtest);
264 GadgetClassMemberList *element =
const_cast<GadgetClassMemberList*
> (&*celement);
265 element->members.push_back (
new MemberAccessor {mt, offset, std::move (accessfunc), infosp, ev, flags});
270GadgetImpl::create_properties ()
276 auto &cml = cml_set();
277 for (
const GadgetClassMemberList &ml : cml)
278 if (ml.classtest (*this))
279 for (const MemberAccessor *m : ml.members) {
280 PropertyGetter getter = [
this,m] (Value &value) { m->func (
this,
nullptr, &value); };
281 PropertySetter setter = [
this,m] (
const Value &value) {
return m->func (
this, &value,
nullptr); };
284 String hints = kvpairs_fetch (infos,
"hints");
285 if (m->flags & MemberDetails::READABLE)
287 if (m->flags & MemberDetails::WRITABLE)
289 if (m->flags & MemberDetails::STORAGE)
291 if (m->flags & MemberDetails::GUI)
293 kvpairs_assign (infos,
"hints=" + hints);
294 Param param { .extras = m->ev, .metadata = infos };
295 this->props_.push_back (PropertyImpl::make_shared (param, getter, setter, lister));
Base type for classes that have a Property.
Base type for classes that have a Property.
virtual GadgetImpl * _parent() const =0
Retrieve parent container.
One entry in a Writ serialization document.
bool in_load() const
Return true during deserialization.
bool in_save() const
Return true during serialization.
#define assert_return(expr,...)
Return from the current function if expr is unmet and issue an assertion warning.
#define return_unless(cond,...)
Return silently if cond does not evaluate to true with return value ...
The Anklang C++ API namespace.
bool string_option_check(const String &optionlist, const String &feature)
Check if an option is set/unset in an options list string.
std::vector< String > StringS
Convenience alias for a std::vector<std::string>.
std::function< ChoiceS(const ParameterProperty &)> PropertyLister
Function type to list Choice Property values.
std::string String
Convenience alias for std::string.
String string_strip(const String &input)
Strip whitespaces from the left and right of a string.
std::function< void(Value &)> PropertyGetter
Function type for Property value getters.
std::function< bool(const Value &)> PropertySetter
Function type for Property value setters.
Value type used to interface with various property types.