GobySoft / dccl

Dynamic Compact Control Language
Other
17 stars 13 forks source link

4.0 threadsafe #101

Closed tsaubergine closed 1 year ago

tsaubergine commented 1 year ago

Non backwards compatible changes:

Calls to FieldCodecManager are no longer static. Rather each Codec contains a FieldCodecManagerLocal with the same API as the old FieldCodecManager except all static methods are no longer static. This means that any code that added entries to FieldCodecManager will need to be rewritten, for example:

// old
FieldCodecManager::add<ArithmeticFieldCodec<int32>>("_arithmetic");
// new
dccl::Codec codec;
codec.manager().add<ArithmeticFieldCodec<int32>>("_arithmetic");

If you have code that needs to support multiple versions of DCCL you can add cpp checks like so:

#include <dccl/version.h>

#if (DCCL_VERSION_MAJOR > 3) || (DCCL_VERSION_MAJOR == 3 && DCCL_VERSION_MINOR >= 1)
#define DCCL_VERSION_3_1_OR_NEWER
#endif 

dccl::Codec codec;
#ifdef DCCL_VERSION_3_1_OR_NEWER
        codec.manager().add<ArithmeticFieldCodec<int32>>("_arithmetic");
#else
        FieldCodecManager::add<ArithmeticFieldCodec<int32>>("_arithmetic");
#endif

Also, this means that when using a non-standard DCCL ID codec, the API for Codec had to change since previously you would load the non-standard ID codec then instantiate the Codec. With this change we have a chicken-and-egg problem, which is solved with a new template constructor for Codec:

// old
dccl::FieldCodecManager::add<MyIDCodec>("my_custom_id");
dccl::Codec codec("my_custom_id");
// new
dccl::Codec codec("my_custom_id", MyIDCodec());

Also, three methods are removed from dccl::DynamicProtobufManager as they provide direct access to member data:

static google::protobuf::DynamicMessageFactory& msg_factory();
static google::protobuf::DescriptorPool& user_descriptor_pool();
static google::protobuf::SimpleDescriptorDatabase& simple_database();

In their place are member functions (with the same name but with "_call" appended) that can be used to call any of the methods of the respective member data class but while locking a mutex during the call.

For example, calling FindAllExtensions on the user_descriptor_pool

// old
dccl::DynamicProtobufManager::user_descriptor_pool().FindAllExtensions(desc, &user_extensions);
// new
dccl::DynamicProtobufManager::user_descriptor_pool_call(&google::protobuf::DescriptorPool::FindAllExtensions, desc, &user_extensions);