Skip to content

Instantly share code, notes, and snippets.

@gavr123456789
Created July 12, 2020 17:46
Show Gist options
  • Save gavr123456789/a61e0aec83012cad14fa345e657c350e to your computer and use it in GitHub Desktop.
Save gavr123456789/a61e0aec83012cad14fa345e657c350e to your computer and use it in GitHub Desktop.
namespace ObjectFactory {
private Gee.Map<Type, Type> _value_types;
public void set_value_type_for_prop_type (Type prop_type, Type value_type) {
if (_value_types == null) {
_value_types = new Gee.HashMap<Type, Type> ();
}
_value_types[prop_type] = value_type;
}
private (unowned ParamSpec)[] get_construct_properties<T> () {
var klass = (ObjectClass) typeof (T).class_ref ();
var props = klass.list_properties ();
(unowned ParamSpec)[] result = new (unowned ParamSpec)[0];
for (var i = 0; i < props.length; i++) {
if ((props[i].flags & ParamFlags.CONSTRUCT) != 0 ||
(props[i].flags & ParamFlags.CONSTRUCT_ONLY) != 0)
{
result.resize (result.length + 1);
result[result.length - 1] = props[i];
prin(props[i].name);
}
}
prin(@"$(result.length) ", result.length);
return result;
}
private (unowned string)[] get_matched_property_names (ParamSpec[] props) {
(unowned string)[] names = new (unowned string)[0];
for (var i = 0; i < props.length; i++) {
foreach (var key_type in _value_types.keys) {
if (props[i].value_type.is_a (key_type)) {
names.resize (names.length + 1);
names[names.length - 1] = props[i].name;
}
}
}
return names;
}
private Value[] get_matched_property_values (ParamSpec[] props) {
Value[] values = new Value[0];
for (var i = 0; i < props.length; i++) {
foreach (var key_type in _value_types.keys) {
if (props[i].value_type.is_a (key_type)) {
values.resize (values.length + 1);
var value = Value(_value_types[key_type]);
value.set_object (Object.new (_value_types[key_type]));
values[values.length - 1] = value;
}
}
}
return values;
}
public T get_instance<T> () {
if (_value_types == null)
return Object.new (typeof (T));
var props = get_construct_properties<T> ();
var names = get_matched_property_names (props);
var values = get_matched_property_values (props);
return Object.new_with_properties (typeof (T), names, values);
}
}
interface Service : Object {
public abstract void serve ();
}
class FoodService : Object, Service {
public void serve () {
message ("Hi, I'm serving food");
}
}
class Client : Object {
public Service service { get; construct; }
public Client (Service service) {
Object (
service: service
);
}
public void use_service () requires (this.service != null) {
message ("Hi, I'm using the service");
this.service.serve ();
}
}
void main () {
// the ObjectFactory will start looking for construct properties of type Service
// and setting them with a new instance of FoodService
ObjectFactory.set_value_type_for_prop_type (typeof (Service), typeof (FoodService));
var client = ObjectFactory.get_instance<Client> ();
client.use_service ();
}
[Print] void prin(string s){
stdout.printf(s + "\n");
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment