From 0a03fc48b62b8e7127ffbf1b7f3ccb98f70b1e90 Mon Sep 17 00:00:00 2001 From: Green Sky Date: Thu, 6 Mar 2025 16:15:50 +0100 Subject: [PATCH] refactor contacts, new interface and events --- src/CMakeLists.txt | 27 +++++++- src/solanaceae/contact/components.hpp | 42 +++++++++--- src/solanaceae/contact/components_id.inl | 10 +++ src/solanaceae/contact/contact_model3.hpp | 30 --------- src/solanaceae/contact/contact_model4.hpp | 31 +++++++++ .../contact/contact_store_events.hpp | 21 ++++++ src/solanaceae/contact/contact_store_i.hpp | 41 ++++++++++++ src/solanaceae/contact/contact_store_impl.cpp | 64 +++++++++++++++++++ src/solanaceae/contact/contact_store_impl.hpp | 23 +++++++ src/solanaceae/contact/fwd.hpp | 17 +++++ 10 files changed, 264 insertions(+), 42 deletions(-) delete mode 100644 src/solanaceae/contact/contact_model3.hpp create mode 100644 src/solanaceae/contact/contact_model4.hpp create mode 100644 src/solanaceae/contact/contact_store_events.hpp create mode 100644 src/solanaceae/contact/contact_store_i.hpp create mode 100644 src/solanaceae/contact/contact_store_impl.cpp create mode 100644 src/solanaceae/contact/contact_store_impl.hpp create mode 100644 src/solanaceae/contact/fwd.hpp diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 10144d7..9d96057 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,12 +1,33 @@ +project(solanaceae_contact C CXX) + add_library(solanaceae_contact INTERFACE - #./solanaceae/contact/components.hpp - #./solanaceae/contact/components_id.inl - #./solanaceae/contact/contact_model3.hpp + ./solanaceae/contact/fwd.hpp + + ./solanaceae/contact/components.hpp + ./solanaceae/contact/components_id.inl + ./solanaceae/contact/contact_model4.hpp + + ./solanaceae/contact/contact_store_events.hpp + ./solanaceae/contact/contact_store_i.hpp ) target_include_directories(solanaceae_contact INTERFACE .) target_compile_features(solanaceae_contact INTERFACE cxx_std_17) target_link_libraries(solanaceae_contact INTERFACE EnTT::EnTT + solanaceae_util +) + +######################################## + +add_library(solanaceae_contact_impl + ./solanaceae/contact/contact_store_impl.hpp + ./solanaceae/contact/contact_store_impl.cpp +) + +target_include_directories(solanaceae_contact_impl PUBLIC .) +target_compile_features(solanaceae_contact_impl PUBLIC cxx_std_17) +target_link_libraries(solanaceae_contact_impl PUBLIC + solanaceae_contact ) diff --git a/src/solanaceae/contact/components.hpp b/src/solanaceae/contact/components.hpp index febaf2c..f476e72 100644 --- a/src/solanaceae/contact/components.hpp +++ b/src/solanaceae/contact/components.hpp @@ -1,13 +1,11 @@ #pragma once -#include "./contact_model3.hpp" +#include "./fwd.hpp" +#include #include #include -// fwd -struct ContactModel3I; - namespace Contact::Components { struct TagSelfWeak {}; @@ -31,24 +29,24 @@ namespace Contact::Components { // self counterpart struct Self { - Contact3 self; + Contact4 self; }; - // tier 1 + // tier 1 ? struct Parent { - Contact3 parent; + Contact4 parent; }; // TODO: maybe rename to children // subs are not exclusive (only is some protocols) // this is not an indicator of a groupchat struct ParentOf { - std::vector subs; + std::vector subs; }; // TODO: this is very hacky // maybe refwrapper? - using ContactModel = ContactModel3I*; + using ContactModel = ContactModel4I*; struct Name { std::string name; @@ -124,6 +122,32 @@ namespace Contact::Components { uint64_t ts {0}; }; + // capabilities, supported by the protocol + // usually not persistent + namespace Caps { + // usually supported, but can mean different things + // eg tox ngc means destorying your group creds + struct TagDeletable {}; + + // can disconnect/reconnect without deleting + struct TagConnectable {}; + + // TODO: some acl thingy + + // message model? + struct TagSendMessage {}; + struct SendMessageSize { uint64_t max {0}; }; + + struct TagSetName {}; + + struct TagSetStatus {}; // none(avail)/away/busy ?? + + struct TagSetStatusText {}; + struct StatusTextSize { uint64_t max {0}; }; + + struct TagSetStatusRich {}; // whatever that means; kvmap? + } // Caps + } // Contact::Components #include "./components_id.inl" diff --git a/src/solanaceae/contact/components_id.inl b/src/solanaceae/contact/components_id.inl index 819b72e..e520770 100644 --- a/src/solanaceae/contact/components_id.inl +++ b/src/solanaceae/contact/components_id.inl @@ -41,5 +41,15 @@ DEFINE_COMP_ID(Contact::Components::FirstSeen) DEFINE_COMP_ID(Contact::Components::LastSeen) DEFINE_COMP_ID(Contact::Components::LastActivity) +DEFINE_COMP_ID(Contact::Components::Caps::TagDeletable) +DEFINE_COMP_ID(Contact::Components::Caps::TagConnectable) +DEFINE_COMP_ID(Contact::Components::Caps::TagSendMessage) +DEFINE_COMP_ID(Contact::Components::Caps::SendMessageSize) +DEFINE_COMP_ID(Contact::Components::Caps::TagSetName) +DEFINE_COMP_ID(Contact::Components::Caps::TagSetStatus) +DEFINE_COMP_ID(Contact::Components::Caps::TagSetStatusText) +DEFINE_COMP_ID(Contact::Components::Caps::StatusTextSize) +DEFINE_COMP_ID(Contact::Components::Caps::TagSetStatusRich) + #undef DEFINE_COMP_ID diff --git a/src/solanaceae/contact/contact_model3.hpp b/src/solanaceae/contact/contact_model3.hpp deleted file mode 100644 index 45b527e..0000000 --- a/src/solanaceae/contact/contact_model3.hpp +++ /dev/null @@ -1,30 +0,0 @@ -#pragma once - -#include -#include - -// strong typing for contacts -enum class Contact3 : uint32_t {}; - -using Contact3Registry = entt::basic_registry; -using Contact3Handle = entt::basic_handle; - -struct ContactModel3I { - virtual ~ContactModel3I(void) {} - - // eg friends, confs, groups - //virtual std::vector getBigContacts(void) = 0; - // eg, all clients in a group - //virtual std::vector getSubContacts(const Contact3& c) = 0; - - //virtual Contact3Handle toSelfStrong(void) = 0; - - //virtual Contact3Handle toBig(void) = 0; - - //virtual Contact3Handle toPersistent(void) = 0; - //virtual Contact3Handle toEphemeral(void) = 0; - - // accept incoming request - virtual void acceptRequest(Contact3 c, std::string_view self_name, std::string_view password) { (void)c,(void)self_name,(void)password; } -}; - diff --git a/src/solanaceae/contact/contact_model4.hpp b/src/solanaceae/contact/contact_model4.hpp new file mode 100644 index 0000000..35af3d2 --- /dev/null +++ b/src/solanaceae/contact/contact_model4.hpp @@ -0,0 +1,31 @@ +#pragma once + +#include "./fwd.hpp" + +#include + +struct ContactModel4I { + virtual ~ContactModel4I(void) {} + + // DRAFT: good idea? make it like acceptRequest? change acceptRequest? + // create and fill in the required info and then tell the CM about it + // eg tox friend requests will use the tox friend id (with nospam+cs) to send a friend request + // or ngc will use chatid to join group + // triggers an construct event on c + virtual bool addContact(Contact4 c) = 0; + + //// eg tox friend id is toxid (with nospam) and include the hello text in the request, but self_name and pw are ignored + //// tox ngc id is chatid, self_name and pw are used, but hello_text is ignored + //// TODO: how to diff??? + //// triggers an construct event on c + //virtual bool addContact(std::string_view id, std::string_view hello_text, std::string_view self_name, std::string_view password); + + // accept incoming request + // triggers an update event on c + virtual bool acceptRequest(Contact4 c, std::string_view self_name, std::string_view password) = 0; + + // delete + // triggers a destroy event on c + virtual bool leave(Contact4 c, std::string_view reason) = 0; +}; + diff --git a/src/solanaceae/contact/contact_store_events.hpp b/src/solanaceae/contact/contact_store_events.hpp new file mode 100644 index 0000000..f5005d5 --- /dev/null +++ b/src/solanaceae/contact/contact_store_events.hpp @@ -0,0 +1,21 @@ +#pragma once + +#include "./fwd.hpp" + +#include +#include + +namespace ContactStore::Events { + + struct Contact4Construct { + const ContactHandle4 e; + }; + struct Contact4Update { + const ContactHandle4 e; + }; + struct Contact4Destory { + const ContactHandle4 e; + }; + +} // ContactStore::Events + diff --git a/src/solanaceae/contact/contact_store_i.hpp b/src/solanaceae/contact/contact_store_i.hpp new file mode 100644 index 0000000..d7f5119 --- /dev/null +++ b/src/solanaceae/contact/contact_store_i.hpp @@ -0,0 +1,41 @@ +#pragma once + +#include "./fwd.hpp" + +#include +#include + +enum class ContactStore4_Event : uint16_t { + contact_construct, + contact_update, + contact_destroy, + + MAX +}; + +struct ContactStore4EventI { + using enumType = ContactStore4_Event; + + virtual ~ContactStore4EventI(void) {} + + virtual bool onEvent(const ContactStore::Events::Contact4Construct&) { return false; } + virtual bool onEvent(const ContactStore::Events::Contact4Update&) { return false; } + virtual bool onEvent(const ContactStore::Events::Contact4Destory&) { return false; } +}; +using ContactStore4EventProviderI = EventProviderI; + +struct ContactStore4I : public ContactStore4EventProviderI{ + static constexpr const char* version {"1"}; + + virtual ContactRegistry4& registry(void) = 0; + virtual ContactHandle4 contactHandle(const Contact4 c) = 0; + + virtual ContactHandle4 getOneContactByID(const ByteSpan id) = 0; + virtual ContactHandle4 getOneContactByID(const Contact4 hint, const ByteSpan id) = 0; + + virtual void throwEventConstruct(const Contact4 c) = 0; + virtual void throwEventUpdate(const Contact4 c) = 0; + //virtual void throwEventUpdate(const Contact4 c, std::vector comp_list) = 0; + virtual void throwEventDestroy(const Contact4 c) = 0; +}; + diff --git a/src/solanaceae/contact/contact_store_impl.cpp b/src/solanaceae/contact/contact_store_impl.cpp new file mode 100644 index 0000000..7efc871 --- /dev/null +++ b/src/solanaceae/contact/contact_store_impl.cpp @@ -0,0 +1,64 @@ +#include "./contact_store_impl.hpp" + +#include "./components.hpp" +#include "./contact_store_events.hpp" + +#include + +#include + +ContactRegistry4& ContactStore4Impl::registry(void) { + return _reg; +} + +ContactHandle4 ContactStore4Impl::contactHandle(const Contact4 c) { + return {_reg, c}; +} + +ContactHandle4 ContactStore4Impl::getOneContactByID(const ByteSpan id) { + // TODO: accelerate + // maybe keep it sorted and binary search? hash table lookup? + for (const auto& [contact, id_comp] : _reg.view().each()) { + if (id == ByteSpan{id_comp.data}) { + return {_reg, contact}; + } + } + + return {_reg, entt::null}; +} + +ContactHandle4 ContactStore4Impl::getOneContactByID(const Contact4 hint, const ByteSpan id) { + // TODO: implement me + return getOneContactByID(id); +} + +void ContactStore4Impl::throwEventConstruct(const Contact4 c) { + std::cout << "CS debug: event construct " << entt::to_integral(c) << "\n"; + dispatch( + ContactStore4_Event::contact_construct, + ContactStore::Events::Contact4Construct{ + ContactHandle4{_reg, c} + } + ); +} + +void ContactStore4Impl::throwEventUpdate(const Contact4 c) { + std::cout << "CS debug: event update " << entt::to_integral(c) << "\n"; + dispatch( + ContactStore4_Event::contact_update, + ContactStore::Events::Contact4Update{ + ContactHandle4{_reg, c} + } + ); +} + +void ContactStore4Impl::throwEventDestroy(const Contact4 c) { + std::cout << "CS debug: event destroy " << entt::to_integral(c) << "\n"; + dispatch( + ContactStore4_Event::contact_destroy, + ContactStore::Events::Contact4Destory{ + ContactHandle4{_reg, c} + } + ); +} + diff --git a/src/solanaceae/contact/contact_store_impl.hpp b/src/solanaceae/contact/contact_store_impl.hpp new file mode 100644 index 0000000..09e830f --- /dev/null +++ b/src/solanaceae/contact/contact_store_impl.hpp @@ -0,0 +1,23 @@ +#pragma once + +#include "./contact_store_i.hpp" +#include "solanaceae/contact/fwd.hpp" + +#include + +// default implementation +struct ContactStore4Impl : public ContactStore4I { + ContactRegistry4& registry(void) override; + ContactHandle4 contactHandle(const Contact4 c) override; + + ContactHandle4 getOneContactByID(const ByteSpan id) override; + ContactHandle4 getOneContactByID(const Contact4 hint, const ByteSpan id) override; + + void throwEventConstruct(const Contact4 c) override; + void throwEventUpdate(const Contact4 c) override; + void throwEventDestroy(const Contact4 c) override; + + private: + entt::basic_registry _reg; +}; + diff --git a/src/solanaceae/contact/fwd.hpp b/src/solanaceae/contact/fwd.hpp new file mode 100644 index 0000000..314c44c --- /dev/null +++ b/src/solanaceae/contact/fwd.hpp @@ -0,0 +1,17 @@ +#pragma once + +#include + +// strong typing for contacts +enum class Contact4 : uint32_t {}; +using ContactRegistry4 = entt::basic_registry; +using ContactHandle4 = entt::basic_handle; + +struct ContactStore4I; +struct ContactModel4I; +namespace ContactStore::Events { + struct Contact4Construct; + struct Contact4Update; + struct Contact4Destory; +} // ContactStore::Events +