2727%include " app/src/swig/serial_dispose.i"
2828%include " app/src/swig/future.i"
2929
30+ // Start of code added to the C++ module file
3031%{
3132#include < algorithm>
3233#include < map>
3334#include < vector>
35+ #include " app/src/callback.h"
3436#include " app/src/cpp_instance_manager.h"
3537#include " remote_config/src/include/firebase/remote_config.h"
3638
3739namespace firebase {
3840namespace remote_config {
3941
42+ // Declare the C++ callback delegate equivalent to C# RemoteConfigUtil.ConfigUpdateDelegate
43+ typedef void (SWIGSTDCALL *ConfigUpdateListener)(const char * app_name, ConfigUpdate* config_update, int error);
44+
4045// Reference count manager for C++ RemoteConfig instance, using pointer as the
4146// key for searching.
4247static CppInstanceManager<RemoteConfig> g_rc_instances;
4348
49+ // App -> C++ ConfigUpdateListener map.
50+ static std::map<App*, firebase::remote_config::ConfigUpdateListenerRegistration> g_registered_listeners;
51+
52+ // Should be set to the C# function FirebaseRemoteConfig.ConfigUpdateMethod
53+ static ConfigUpdateListener g_config_updated = nullptr ;
54+
4455// Internal struct used to pass the Remote Config stored data from C++ to C#.
4556struct ConfigValueInternal {
4657 // The raw data.
@@ -49,36 +60,61 @@ struct ConfigValueInternal {
4960 ValueSource source;
5061};
5162
63+ // Wrapper that calls g_config_updated. Should be used with the
64+ // callback logic to guarantee it is on the Unity thread.
65+ static void CallConfigUpdate (ConfigUpdate cu, RemoteConfigError error, const char * name) {
66+ if (g_config_updated) {
67+ // Should be calling FirebaseRemoteConfig.ConfigUpdateMethod
68+ g_config_updated (name, &cu, static_cast <int >(error));
69+ }
70+ }
71+ // Called by C# to register a RemoteConfig instance for config updates,
72+ // provided via the callback method provided.
73+ void SetConfigUpdateCallback (RemoteConfig* rc, firebase::remote_config::ConfigUpdateListener on_config_updated) {
74+ // If given a method, save it, and add a new listener for Config Updates.
75+ if (on_config_updated) {
76+ if (!g_config_updated) {
77+ g_config_updated = on_config_updated;
78+ }
79+ std::string app_name = rc->app ()->name ();
80+ ConfigUpdateListenerRegistration registration = rc->AddOnConfigUpdateListener ([app_name](ConfigUpdate&& cu, RemoteConfigError error) {
81+ // Queue up a call to g_config_updated
82+ ConfigUpdate cuLocal = std::move (cu);
83+ firebase::callback::AddCallback (
84+ new firebase::callback::CallbackValue2String1<ConfigUpdate, RemoteConfigError>(
85+ cuLocal, error, app_name.c_str (), CallConfigUpdate));
86+ });
87+
88+ // Save the registration in a map so that it can be removed later if needed.
89+ g_registered_listeners[rc->app ()] = registration;
90+ } else {
91+ // Remove the listener, and cleanup the callback if no more remain.
92+ ConfigUpdateListenerRegistration registration = g_registered_listeners[rc->app ()];
93+ g_registered_listeners.erase (rc->app ());
94+ registration.Remove ();
95+
96+ if (g_registered_listeners.empty ()) {
97+ g_config_updated = nullptr ;
98+ }
99+ }
100+ }
101+
52102} // remote_config
53103} // firebase
54- %}
104+
105+ %} // End of code added to the C++ module file
55106
56107// All outputs of CharVector should instead be IEnumerable<byte>
57108%typemap(cstype, out=" global::System.Collections.Generic.IEnumerable<byte>" ) std::vector<unsigned char > " CharVector" ;
58109// All outputs of StringList should instead be IEnumerable<string>
59110%typemap(cstype, out=" global::System.Collections.Generic.IEnumerable<string>" ) std::vector<std::string> " StringList" ;
60111
61- // Ignore all the deprecated static functions
62- %ignore firebase::remote_config::Initialize;
63- %ignore firebase::remote_config::Terminate;
64- %ignore firebase::remote_config::SetDefaults;
65- %ignore firebase::remote_config::GetConfigSetting;
66- %ignore firebase::remote_config::SetConfigSetting;
67- %ignore firebase::remote_config::GetBoolean;
68- %ignore firebase::remote_config::GetLong;
69- %ignore firebase::remote_config::GetDouble;
70- %ignore firebase::remote_config::GetString;
71- %ignore firebase::remote_config::GetData;
72- %ignore firebase::remote_config::GetKeysByPrefix;
73- %ignore firebase::remote_config::GetKeys;
74- %ignore firebase::remote_config::Fetch;
75- %ignore firebase::remote_config::ActivateFetched;
76- %ignore firebase::remote_config::GetInfo;
77-
78112// Ignore unused structs and enums
79113%ignore firebase::remote_config::ValueInfo;
80114%ignore firebase::remote_config::ConfigKeyValue;
81115%ignore firebase::remote_config::ConfigSetting;
116+ %ignore firebase::remote_config::RemoteConfigError;
117+ %ignore firebase::remote_config::ConfigUpdateListenerRegistration;
82118
83119// Configure the ConfigInfo class
84120%csmethodmodifiers fetch_time " internal" ;
@@ -131,6 +167,8 @@ struct ConfigValueInternal {
131167
132168%rename (ConfigSettingsInternal) firebase::remote_config::ConfigSettings;
133169
170+ %rename (ConfigUpdateInternal) firebase::remote_config::ConfigUpdate;
171+
134172// Configure properties for get / set methods on the FirebaseRemoteConfigInternal class.
135173%attribute(firebase::remote_config::RemoteConfig, firebase::App*, App, app);
136174
@@ -147,6 +185,7 @@ struct ConfigValueInternal {
147185%ignore firebase::remote_config::RemoteConfig::GetData;
148186// Ignore GetAll, as we do not rely on the C++ function for it.
149187%ignore firebase::remote_config::RemoteConfig::GetAll;
188+ %ignore firebase::remote_config::RemoteConfig::AddOnConfigUpdateListener;
150189
151190%typemap(cscode) firebase::remote_config::RemoteConfig %{
152191 // Generates a key that uniquely identifies this instance.
@@ -176,8 +215,13 @@ struct ConfigValueInternal {
176215 System.GC .SuppressFinalize (this );
177216}
178217
218+ SWIG_MAP_CFUNC_TO_CSDELEGATE (
219+ firebase::remote_config::ConfigUpdateListener,
220+ Firebase.RemoteConfig.RemoteConfigUtil.ConfigUpdateDelegate)
221+
179222%include "remote_config/src/include/firebase/remote_config.h"
180223
224+ // Start of C++ definitions that Swig needs to know of, to generate C# for
181225namespace firebase {
182226namespace remote_config {
183227
@@ -186,10 +230,17 @@ struct ConfigValueInternal {
186230 ValueSource source;
187231};
188232
233+ void SetConfigUpdateCallback (firebase::remote_config::RemoteConfig* rc,
234+ firebase::remote_config::ConfigUpdateListener config_listener);
235+
189236}
190- }
237+ } // End of C++ definitions
238+
191239
192240%pragma(csharp) modulecode=%{
241+
242+ internal delegate void ConfigUpdateDelegate (string appName, System.IntPtr configUpdatePtr, int error);
243+
193244 // / The C++ mapping requires a StringStringMap, so convert the more generic
194245 // / dictionary into that map.
195246 internal static StringStringMap ConvertDictionaryToMap (
0 commit comments