Browse Source

Support explicit DataTypeRegister setup for DataModel. (#409)

Eugene Kozlov 2 years ago
parent
commit
c50911b2af

+ 3 - 2
Include/RmlUi/Core/Context.h

@@ -248,8 +248,9 @@ public:
 	/// Creates a data model.
 	/// The returned constructor can be used to bind data variables. Elements can bind to the model using the attribute 'data-model="name"'.
 	/// @param[in] name The name of the data model.
+	/// @param[in] data_type_register The data type register to use for the data model, or null to use the default register.
 	/// @return A constructor for the data model, or empty if it could not be created.
-	DataModelConstructor CreateDataModel(const String& name);
+	DataModelConstructor CreateDataModel(const String& name, DataTypeRegister* data_type_register = nullptr);
 
 	/// Retrieves the constructor for an existing data model.
 	/// The returned constructor can be used to add additional bindings to an existing model.
@@ -354,7 +355,7 @@ private:
 	using DataModels = UnorderedMap<String, UniquePtr<DataModel>>;
 	DataModels data_models;
 
-	UniquePtr<DataTypeRegister> data_type_register;
+	UniquePtr<DataTypeRegister> default_data_type_register;
 
 	// Internal callback for when an element is detached or removed from the hierarchy.
 	void OnElementDetach(Element* element);

+ 1 - 1
Include/RmlUi/Core/DataModelHandle.h

@@ -62,7 +62,7 @@ public:
 	using DataEventMemberFunc = void(T::*)(DataModelHandle, Event&, const VariantList&);
 
 	DataModelConstructor();
-	DataModelConstructor(DataModel* model, DataTypeRegister* type_register);
+	explicit DataModelConstructor(DataModel* model);
 
 	// Return a handle to the data model being constructed, which can later be used to synchronize variables and update the model.
 	DataModelHandle GetModelHandle() const;

+ 10 - 9
Source/Core/Context.cpp

@@ -921,15 +921,19 @@ void Context::SetInstancer(ContextInstancer* _instancer)
 	instancer = _instancer;
 }
 
-DataModelConstructor Context::CreateDataModel(const String& name)
+DataModelConstructor Context::CreateDataModel(const String& name, DataTypeRegister* data_type_register)
 {
 	if (!data_type_register)
-		data_type_register = MakeUnique<DataTypeRegister>();
+	{
+		if (!default_data_type_register)
+			default_data_type_register = MakeUnique<DataTypeRegister>();
+		data_type_register = default_data_type_register.get();
+	}
 
-	auto result = data_models.emplace(name, MakeUnique<DataModel>(data_type_register->GetTransformFuncRegister()));
+	auto result = data_models.emplace(name, MakeUnique<DataModel>(data_type_register));
 	bool inserted = result.second;
 	if (inserted)
-		return DataModelConstructor(result.first->second.get(), data_type_register.get());
+		return DataModelConstructor(result.first->second.get());
 
 	Log::Message(Log::LT_ERROR, "Data model name '%s' already exists.", name.c_str());
 	return DataModelConstructor();
@@ -937,11 +941,8 @@ DataModelConstructor Context::CreateDataModel(const String& name)
 
 DataModelConstructor Context::GetDataModel(const String& name)
 {
-	if (data_type_register)
-	{
-		if (DataModel* model = GetDataModelPtr(name))
-			return DataModelConstructor(model, data_type_register.get());
-	}
+	if (DataModel* model = GetDataModelPtr(name))
+		return DataModelConstructor(model);
 
 	Log::Message(Log::LT_ERROR, "Data model name '%s' could not be found.", name.c_str());
 	return DataModelConstructor();

+ 3 - 2
Source/Core/DataModel.cpp

@@ -120,7 +120,8 @@ static String DataAddressToString(const DataAddress& address)
 	return result;
 }
 
-DataModel::DataModel(const TransformFuncRegister* transform_register) : transform_register(transform_register)
+DataModel::DataModel(DataTypeRegister* data_type_register) :
+	data_type_register(data_type_register)
 {
 	views = MakeUnique<DataViews>();
 	controllers = MakeUnique<DataControllers>();
@@ -350,7 +351,7 @@ void DataModel::DirtyAllVariables() {
 
 bool DataModel::CallTransform(const String& name, const VariantList& arguments, Variant& out_result) const
 {
-	if (transform_register)
+	if (const auto transform_register = data_type_register->GetTransformFuncRegister())
 		return transform_register->Call(name, arguments, out_result);
 	return false;
 }

+ 6 - 2
Source/Core/DataModel.h

@@ -46,7 +46,7 @@ class FuncDefinition;
 
 class DataModel : NonCopyMoveable {
 public:
-	DataModel(const TransformFuncRegister* transform_register = nullptr);
+	DataModel(DataTypeRegister* data_type_register = nullptr);
 	~DataModel();
 
 	void AddView(DataViewPtr view);
@@ -80,6 +80,10 @@ public:
 
 	bool Update(bool clear_dirty_variables);
 
+	inline DataTypeRegister* GetDataTypeRegister() const {
+		return data_type_register;
+	}
+
 private:
 	UniquePtr<DataViews> views;
 	UniquePtr<DataControllers> controllers;
@@ -93,7 +97,7 @@ private:
 	using ScopedAliases = UnorderedMap<Element*, SmallUnorderedMap<String, DataAddress>>;
 	ScopedAliases aliases;
 
-	const TransformFuncRegister* transform_register;
+	DataTypeRegister* data_type_register;
 
 	SmallUnorderedSet<Element*> attached_elements;
 };

+ 2 - 2
Source/Core/DataModelHandle.cpp

@@ -50,8 +50,8 @@ void DataModelHandle::DirtyAllVariables() {
 
 DataModelConstructor::DataModelConstructor() : model(nullptr), type_register(nullptr) {}
 
-DataModelConstructor::DataModelConstructor(DataModel* model, DataTypeRegister* type_register) : model(model), type_register(type_register) {
-	RMLUI_ASSERT(model && type_register);
+DataModelConstructor::DataModelConstructor(DataModel* model) : model(model), type_register(model->GetDataTypeRegister()) {
+	RMLUI_ASSERT(model);
 }
 
 DataModelHandle DataModelConstructor::GetModelHandle() const {

+ 2 - 2
Tests/Source/Benchmarks/DataExpression.cpp

@@ -37,7 +37,7 @@ using namespace Rml;
 using namespace ankerl;
 
 static DataTypeRegister type_register;
-static DataModel model(type_register.GetTransformFuncRegister());
+static DataModel model(&type_register);
 static DataExpressionInterface interface(&model, nullptr);
 
 
@@ -47,7 +47,7 @@ TEST_CASE("data_expressions")
 	String color_name = "color";
 	Colourb color_value = Colourb(180, 100, 255);
 
-	DataModelConstructor constructor(&model, &type_register);
+	DataModelConstructor constructor(&model);
 	constructor.Bind("radius", &radius);
 	constructor.Bind("color_name", &color_name);
 	constructor.BindFunc("color_value", [&](Variant& variant) {

+ 2 - 2
Tests/Source/UnitTests/DataExpression.cpp

@@ -34,7 +34,7 @@
 using namespace Rml;
 
 static DataTypeRegister type_register;
-static DataModel model(type_register.GetTransformFuncRegister());
+static DataModel model(&type_register);
 static DataExpressionInterface interface(&model, nullptr);
 
 static String TestExpression(const String& expression)
@@ -94,7 +94,7 @@ TEST_CASE("Data expressions")
 	String color_name = "color";
 	Colourb color_value = Colourb(180, 100, 255);
 
-	DataModelConstructor constructor(&model, &type_register);
+	DataModelConstructor constructor(&model);
 	constructor.Bind("radius", &radius);
 	constructor.Bind("color_name", &color_name);
 	constructor.Bind("num_trolls", &num_trolls);

+ 2 - 2
Tests/Source/UnitTests/DataModel.cpp

@@ -51,10 +51,10 @@ TEST_CASE("Data variables")
 		FunArray more_fun;
 	};
 
-	DataModel model;
 	DataTypeRegister types;
+	DataModel model(&types);
 
-	DataModelConstructor handle(&model, &types);
+	DataModelConstructor handle(&model);
 
 	// Setup data type register
 	{