Created
January 14, 2024 20:21
-
-
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.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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