refactor contacts, new interface and events

This commit is contained in:
Green Sky 2025-03-06 16:15:50 +01:00
parent e2917c497c
commit 0a03fc48b6
No known key found for this signature in database
GPG Key ID: DBE05085D874AB4A
10 changed files with 264 additions and 42 deletions

View File

@ -1,12 +1,33 @@
project(solanaceae_contact C CXX)
add_library(solanaceae_contact INTERFACE add_library(solanaceae_contact INTERFACE
#./solanaceae/contact/components.hpp ./solanaceae/contact/fwd.hpp
#./solanaceae/contact/components_id.inl
#./solanaceae/contact/contact_model3.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_include_directories(solanaceae_contact INTERFACE .)
target_compile_features(solanaceae_contact INTERFACE cxx_std_17) target_compile_features(solanaceae_contact INTERFACE cxx_std_17)
target_link_libraries(solanaceae_contact INTERFACE target_link_libraries(solanaceae_contact INTERFACE
EnTT::EnTT 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
) )

View File

@ -1,13 +1,11 @@
#pragma once #pragma once
#include "./contact_model3.hpp" #include "./fwd.hpp"
#include <cstdint>
#include <string> #include <string>
#include <vector> #include <vector>
// fwd
struct ContactModel3I;
namespace Contact::Components { namespace Contact::Components {
struct TagSelfWeak {}; struct TagSelfWeak {};
@ -31,24 +29,24 @@ namespace Contact::Components {
// self counterpart // self counterpart
struct Self { struct Self {
Contact3 self; Contact4 self;
}; };
// tier 1 // tier 1 ?
struct Parent { struct Parent {
Contact3 parent; Contact4 parent;
}; };
// TODO: maybe rename to children // TODO: maybe rename to children
// subs are not exclusive (only is some protocols) // subs are not exclusive (only is some protocols)
// this is not an indicator of a groupchat // this is not an indicator of a groupchat
struct ParentOf { struct ParentOf {
std::vector<Contact3> subs; std::vector<Contact4> subs;
}; };
// TODO: this is very hacky // TODO: this is very hacky
// maybe refwrapper? // maybe refwrapper?
using ContactModel = ContactModel3I*; using ContactModel = ContactModel4I*;
struct Name { struct Name {
std::string name; std::string name;
@ -124,6 +122,32 @@ namespace Contact::Components {
uint64_t ts {0}; 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 } // Contact::Components
#include "./components_id.inl" #include "./components_id.inl"

View File

@ -41,5 +41,15 @@ DEFINE_COMP_ID(Contact::Components::FirstSeen)
DEFINE_COMP_ID(Contact::Components::LastSeen) DEFINE_COMP_ID(Contact::Components::LastSeen)
DEFINE_COMP_ID(Contact::Components::LastActivity) 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 #undef DEFINE_COMP_ID

View File

@ -1,30 +0,0 @@
#pragma once
#include <entt/entity/registry.hpp>
#include <entt/entity/handle.hpp>
// strong typing for contacts
enum class Contact3 : uint32_t {};
using Contact3Registry = entt::basic_registry<Contact3>;
using Contact3Handle = entt::basic_handle<Contact3Registry>;
struct ContactModel3I {
virtual ~ContactModel3I(void) {}
// eg friends, confs, groups
//virtual std::vector<Contact3> getBigContacts(void) = 0;
// eg, all clients in a group
//virtual std::vector<Contact3> 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; }
};

View File

@ -0,0 +1,31 @@
#pragma once
#include "./fwd.hpp"
#include <string_view>
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;
};

View File

@ -0,0 +1,21 @@
#pragma once
#include "./fwd.hpp"
#include <entt/entity/registry.hpp>
#include <entt/entity/handle.hpp>
namespace ContactStore::Events {
struct Contact4Construct {
const ContactHandle4 e;
};
struct Contact4Update {
const ContactHandle4 e;
};
struct Contact4Destory {
const ContactHandle4 e;
};
} // ContactStore::Events

View File

@ -0,0 +1,41 @@
#pragma once
#include "./fwd.hpp"
#include <solanaceae/util/span.hpp>
#include <solanaceae/util/event_provider.hpp>
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<ContactStore4EventI>;
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<entt::id_type> comp_list) = 0;
virtual void throwEventDestroy(const Contact4 c) = 0;
};

View File

@ -0,0 +1,64 @@
#include "./contact_store_impl.hpp"
#include "./components.hpp"
#include "./contact_store_events.hpp"
#include <entt/entity/handle.hpp>
#include <iostream>
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<Contact::Components::ID>().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}
}
);
}

View File

@ -0,0 +1,23 @@
#pragma once
#include "./contact_store_i.hpp"
#include "solanaceae/contact/fwd.hpp"
#include <entt/entity/registry.hpp>
// 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<Contact4> _reg;
};

View File

@ -0,0 +1,17 @@
#pragma once
#include <entt/entity/fwd.hpp>
// strong typing for contacts
enum class Contact4 : uint32_t {};
using ContactRegistry4 = entt::basic_registry<Contact4>;
using ContactHandle4 = entt::basic_handle<ContactRegistry4>;
struct ContactStore4I;
struct ContactModel4I;
namespace ContactStore::Events {
struct Contact4Construct;
struct Contact4Update;
struct Contact4Destory;
} // ContactStore::Events