Skip to content

Instantly share code, notes, and snippets.

@nrbnlulu
Created January 14, 2024 20:21
Show Gist options
  • Save nrbnlulu/99d41e87afb8c20ba31d91526f2cb4ef to your computer and use it in GitHub Desktop.
Save nrbnlulu/99d41e87afb8c20ba31d91526f2cb4ef to your computer and use it in GitHub Desktop.
Try to implement how to qtgqlcodegen would create types and their proxies in more verstile way.
template<typename T>
struct SubscribeAbleField;
template<typename T>
struct InSyncValue{
std::function<void(const T&)> on_changed;
void notify(const SubscribeAbleField<T>* sub){
on_changed(sub->value);
}
};
template<typename T>
struct SubscribeAbleField{
std::list<std::shared_ptr<InSyncValue<T>>> subscribers;
T value;
void subscribe(const std::shared_ptr<InSyncValue<T>>& subscriber){
subscribers.push_back(subscriber);
}
void set_value(const T & v){
value = v;
for (auto& subscriber: subscribers){
subscriber->notify(this);
}
}
void unsubscribe(const std::shared_ptr<InSyncValue<T>> &subscriber){
subscribers.remove(subscriber);
}
};
struct BaseRecord{
/*
* the id of the record.
* should return the unique id of the type if exists.
* otherwise, returns the most recent path to a type with an id.
*/
virtual std::string get_unique_identifier() {
return "";
};
virtual void collect_garbage() {};
virtual bool can_be_garbage_collected() {
return true;
};
};
struct UserRecord: public BaseRecord{
static const inline std::string typename_ = "User";
std::unordered_map<std::string, SubscribeAbleField<std::string>> name_subscribers;
SubscribeAbleField<std::string> id;
SubscribeAbleField<int> age;
std::unordered_map<std::string, SubscribeAbleField<std::list<std::string>>> friends_subscribers;
std::string get_unique_identifier() override{
return typename_ + ":" + id.value;
}
void set_id(const std::string & v){
id.set_value(v);
};
void set_friends(const std::string & args, const std::list<std::string> & v){
friends_subscribers[args].set_value(v);
};
void set_age(const int& v){
age.set_value(v);
};
void set_name(const std::string & args, const std::string & v){
name_subscribers[args].set_value(v);
};
void collect_garbage() override{
for (auto &[_, subs]: name_subscribers){
if (subs.subscribers.empty()){
name_subscribers.erase(_);
}
}
for (auto &[_, subs]: friends_subscribers){
if (subs.subscribers.empty()){
friends_subscribers.erase(_);
}
}
if(name_subscribers.empty())
name_subscribers.clear();
}
bool can_be_garbage_collected() override{
return name_subscribers.empty() && friends_subscribers.empty() && age.subscribers.empty();
}
};
struct UserProxy{
InSyncValue<std::string> id;
InSyncValue<int> age;
InSyncValue<std::string> name;
InSyncValue<std::list<>>
};
int main(){
std::map<std::string, std::shared_ptr<BaseRecord>> cache{};
auto user1_record = std::make_shared<UserRecord>();
user1_record->id.set_value("1");
auto user2_record = std::make_shared<UserRecord>();
user2_record->id.set_value("2");
cache[user1_record->get_unique_identifier()] = user1_record;
cache[user2_record->get_unique_identifier()] = user2_record;
user1_record->set_friends("conected(true)", {user2_record->get_unique_identifier()});
user2_record->set_friends("conected(true)", {user1_record->get_unique_identifier()});
cache["User:1"] = std::make_shared<UserRecord>();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment