Skip to content

Commit 0ffab38

Browse files
committed
AAPXS v2: simplify TypedClientAAPXS implementations by common async callers.
Typical AAPXS developers who still provides synchronous client API should not always have to deal with asynchronous calls by themselves. It is overcomplicated.
1 parent 33e4d83 commit 0ffab38

File tree

6 files changed

+79
-96
lines changed

6 files changed

+79
-96
lines changed

androidaudioplugin/src/main/cpp/core/aapxs/aapxs-runtime.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,3 +84,21 @@ aap::xs::AAPXSServiceDispatcher::populateAAPXSInitiatorInstance(
8484
sendHostAAPXSRequest};
8585
return instance;
8686
}
87+
88+
void aap::xs::TypedClientAAPXS::getVoidCallback(void* callbackContext, AndroidAudioPlugin* plugin, int32_t requestId) {
89+
auto callbackData = (WithPromise<TypedClientAAPXS, int32_t>*) callbackContext;
90+
callbackData->promise->set_value(0); // dummy result
91+
}
92+
93+
void aap::xs::TypedClientAAPXS::callVoidFunctionSynchronously(int32_t opcode) {
94+
// FIXME: use spinlock instead of std::promise and std::future, as getPresetCount() and getPresetIndex() must be RT_SAFE.
95+
std::promise<int32_t> promise{};
96+
uint32_t requestId = aapxs_instance->get_new_request_id(aapxs_instance);
97+
auto future = promise.get_future();
98+
WithPromise<TypedClientAAPXS, int32_t> callbackData{this, &promise};
99+
AAPXSRequestContext request{getVoidCallback, &callbackData, serialization, uri, requestId, opcode};
100+
101+
aapxs_instance->send_aapxs_request(aapxs_instance, &request);
102+
103+
future.wait();
104+
}

androidaudioplugin/src/main/cpp/core/aapxs/parameters-aapxs.cpp

Lines changed: 7 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -70,56 +70,33 @@ void aap::xs::AAPXSDefinition_Parameters::aapxs_parameters_process_incoming_host
7070

7171
// AAPXSParametersClient
7272

73-
template<typename T>
74-
void aap::xs::ParametersClientAAPXS::getParameterTypedCallback(void *callbackContext,
75-
AndroidAudioPlugin *plugin,
76-
int32_t requestId) {
77-
auto callbackData = (WithPromise<ParametersClientAAPXS, T>*) callbackContext;
78-
auto thiz = (ParametersClientAAPXS*) callbackData->context;
79-
T result = *(T*) (thiz->serialization->data);
80-
callbackData->promise->set_value(result);
81-
}
82-
83-
template<typename T>
84-
T aap::xs::ParametersClientAAPXS::callTypedParametersFunction(int32_t opcode) {
85-
// FIXME: use spinlock instead of std::promise and std::future, as getPresetCount() and getPresetIndex() must be RT_SAFE.
86-
std::promise<T> promise{};
87-
uint32_t requestId = initiatorInstance->get_new_request_id(initiatorInstance);
88-
auto future = promise.get_future();
89-
WithPromise<ParametersClientAAPXS, T> callbackData{this, &promise};
90-
AAPXSRequestContext request{getParameterTypedCallback<T>, &callbackData, serialization, AAP_PARAMETERS_EXTENSION_URI, requestId, opcode};
91-
92-
initiatorInstance->send_aapxs_request(initiatorInstance, &request);
93-
94-
future.wait();
95-
return future.get();
96-
}
97-
9873
int32_t aap::xs::ParametersClientAAPXS::getParameterCount() {
99-
return callTypedParametersFunction<int32_t>(OPCODE_PARAMETERS_GET_PARAMETER_COUNT);
74+
return callTypedFunctionSynchronously<int32_t>(OPCODE_PARAMETERS_GET_PARAMETER_COUNT);
10075
}
10176

10277
aap_parameter_info_t aap::xs::ParametersClientAAPXS::getParameter(int32_t index) {
10378
*((int32_t*) serialization->data) = index;
104-
return callTypedParametersFunction<aap_parameter_info_t>(OPCODE_PARAMETERS_GET_PARAMETER_COUNT);
79+
return callTypedFunctionSynchronously<aap_parameter_info_t>(
80+
OPCODE_PARAMETERS_GET_PARAMETER_COUNT);
10581
}
10682

10783
double aap::xs::ParametersClientAAPXS::getProperty(int32_t index, int32_t propertyId) {
10884
*((int32_t*) serialization->data) = index;
10985
*((int32_t*) serialization->data + 1) = propertyId;
110-
return callTypedParametersFunction<double>(OPCODE_PARAMETERS_GET_PARAMETER_COUNT);
86+
return callTypedFunctionSynchronously<double>(OPCODE_PARAMETERS_GET_PARAMETER_COUNT);
11187
}
11288

11389
int32_t aap::xs::ParametersClientAAPXS::getEnumerationCount(int32_t index) {
11490
*((int32_t*) serialization->data) = index;
115-
return callTypedParametersFunction<int32_t>(OPCODE_PARAMETERS_GET_PARAMETER_COUNT);
91+
return callTypedFunctionSynchronously<int32_t>(OPCODE_PARAMETERS_GET_PARAMETER_COUNT);
11692
}
11793

11894
aap_parameter_enum_t
11995
aap::xs::ParametersClientAAPXS::getEnumeration(int32_t index, int32_t enumIndex) {
12096
*((int32_t*) serialization->data) = index;
12197
*((int32_t*) serialization->data + 1) = enumIndex;
122-
return callTypedParametersFunction<aap_parameter_enum_t>(OPCODE_PARAMETERS_GET_PARAMETER_COUNT);
98+
return callTypedFunctionSynchronously<aap_parameter_enum_t>(
99+
OPCODE_PARAMETERS_GET_PARAMETER_COUNT);
123100
}
124101

125102
void aap::xs::ParametersServiceAAPXS::notifyParametersChanged() {

androidaudioplugin/src/main/cpp/core/aapxs/parameters-aapxs.h

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -58,22 +58,12 @@ namespace aap::xs {
5858
}
5959
};
6060

61-
class ParametersClientAAPXS {
62-
AAPXSInitiatorInstance *initiatorInstance;
63-
AAPXSSerializationContext *serialization;
64-
65-
template<typename T>
66-
static void getParameterTypedCallback(void* callbackContext, AndroidAudioPlugin* plugin, int32_t requestId);
67-
static void getParameterCallback(void* callbackContext, AndroidAudioPlugin* plugin, int32_t requestId);
68-
static void getEnumerationCallback(void* callbackContext, AndroidAudioPlugin* plugin, int32_t requestId);
69-
61+
class ParametersClientAAPXS : public TypedClientAAPXS {
7062
public:
7163
ParametersClientAAPXS(AAPXSInitiatorInstance* initiatorInstance, AAPXSSerializationContext* serialization)
72-
: initiatorInstance(initiatorInstance), serialization(serialization) {
64+
: TypedClientAAPXS(AAP_PARAMETERS_EXTENSION_URI, initiatorInstance, serialization) {
7365
}
7466

75-
template<typename T>
76-
T callTypedParametersFunction(int32_t opcode);
7767
int32_t getParameterCount();
7868
aap_parameter_info_t getParameter(int32_t index);
7969
double getProperty(int32_t index, int32_t propertyId);

androidaudioplugin/src/main/cpp/core/aapxs/presets-aapxs.cpp

Lines changed: 8 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -97,55 +97,22 @@ void aap::xs::AAPXSDefinition_Presets::aapxs_presets_process_incoming_host_aapxs
9797

9898
// Strongly-typed client implementation (plugin extension functions)
9999

100-
void aap::xs::PresetsClientAAPXS::getPresetIntCallback(void* callbackContext, AndroidAudioPlugin* plugin, int32_t requestId) {
101-
auto callbackData = (WithPromise<PresetsClientAAPXS, int32_t>*) callbackContext;
102-
auto thiz = (PresetsClientAAPXS*) callbackData->context;
103-
int32_t result = *(int32_t*) (thiz->serialization->data);
104-
callbackData->promise->set_value(result);
105-
}
106-
107-
int32_t aap::xs::PresetsClientAAPXS::callIntPresetFunction(int32_t opcode) {
108-
// FIXME: use spinlock instead of std::promise and std::future, as getPresetCount() and getPresetIndex() must be RT_SAFE.
109-
std::promise<int32_t> promise{};
110-
uint32_t requestId = initiatorInstance->get_new_request_id(initiatorInstance);
111-
auto future = promise.get_future();
112-
WithPromise<PresetsClientAAPXS, int32_t> callbackData{this, &promise};
113-
AAPXSRequestContext request{getPresetIntCallback, &callbackData, serialization, AAP_PRESETS_EXTENSION_URI, requestId, opcode};
114-
115-
initiatorInstance->send_aapxs_request(initiatorInstance, &request);
116-
117-
future.wait();
118-
return future.get();
119-
}
120-
121100
int32_t aap::xs::PresetsClientAAPXS::getPresetCount() {
122-
return callIntPresetFunction(OPCODE_GET_PRESET_COUNT);
101+
return callTypedFunctionSynchronously<int32_t>(OPCODE_GET_PRESET_COUNT);
123102
}
124103

125104
int32_t aap::xs::PresetsClientAAPXS::getPresetIndex() {
126-
return callIntPresetFunction(OPCODE_GET_PRESET_INDEX);
127-
}
128-
129-
void aap::xs::PresetsClientAAPXS::getPresetCallback(void* callbackContext, AndroidAudioPlugin* plugin, int32_t requestId) {
130-
auto callbackData = (WithPromise<PresetsClientAAPXS, int32_t>*) callbackContext;
131-
auto thiz = (PresetsClientAAPXS*) callbackData->context;
132-
int32_t result = *(int32_t*) (thiz->serialization->data);
133-
callbackData->promise->set_value(result);
105+
return callTypedFunctionSynchronously<int32_t>(OPCODE_GET_PRESET_INDEX);
134106
}
135107

136108
void aap::xs::PresetsClientAAPXS::getPreset(int32_t index, aap_preset_t &preset) {
137-
// FIXME: use spinlock instead of std::promise and std::future, as getPresetCount() and getPresetIndex() must be RT_SAFE.
138-
std::promise<int32_t> promise{};
139-
uint32_t requestId = initiatorInstance->get_new_request_id(initiatorInstance);
140-
auto future = promise.get_future();
141-
WithPromise<PresetsClientAAPXS, int32_t> callbackData{this, &promise};
142-
AAPXSRequestContext request{getPresetCallback, &callbackData, serialization, AAP_PRESETS_EXTENSION_URI, requestId, OPCODE_GET_PRESET_DATA};
143-
109+
// request
110+
// - 0..3: index
144111
*(int32_t*) (serialization->data) = index;
145-
initiatorInstance->send_aapxs_request(initiatorInstance, &request);
146112

147-
future.wait();
148-
// response (offset-range: content)
113+
callVoidFunctionSynchronously(OPCODE_GET_PRESET_DATA);
114+
115+
// response
149116
// - 0..3 : stable ID
150117
// - 4..259 : name (fixed length char buffer)
151118
preset.id = *((int32_t *) serialization->data);
@@ -154,12 +121,8 @@ void aap::xs::PresetsClientAAPXS::getPreset(int32_t index, aap_preset_t &preset)
154121
}
155122

156123
void aap::xs::PresetsClientAAPXS::setPresetIndex(int32_t index) {
157-
// we do not wait for the result, so no promise<T> involved
158-
uint32_t requestId = initiatorInstance->get_new_request_id(initiatorInstance);
159-
AAPXSRequestContext request{nullptr, nullptr, serialization, AAP_PRESETS_EXTENSION_URI, requestId, OPCODE_GET_PRESET_DATA};
160-
161124
*(int32_t*) (serialization->data) = index;
162-
initiatorInstance->send_aapxs_request(initiatorInstance, &request);
125+
callVoidFunctionSynchronously(OPCODE_SET_PRESET_INDEX);
163126
}
164127

165128
// Strongly-typed service implementation (host extension functions)

androidaudioplugin/src/main/cpp/core/aapxs/presets-aapxs.h

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -58,19 +58,12 @@ namespace aap::xs {
5858
}
5959
};
6060

61-
class PresetsClientAAPXS {
62-
AAPXSInitiatorInstance *initiatorInstance;
63-
AAPXSSerializationContext *serialization;
64-
65-
static void getPresetIntCallback(void* callbackContext, AndroidAudioPlugin* plugin, int32_t requestId);
66-
static void getPresetCallback(void* callbackContext, AndroidAudioPlugin* plugin, int32_t requestId);
67-
61+
class PresetsClientAAPXS : public TypedClientAAPXS {
6862
public:
6963
PresetsClientAAPXS(AAPXSInitiatorInstance* initiatorInstance, AAPXSSerializationContext* serialization)
70-
: initiatorInstance(initiatorInstance), serialization(serialization) {
64+
: TypedClientAAPXS(AAP_PRESETS_EXTENSION_URI, initiatorInstance, serialization) {
7165
}
7266

73-
int32_t callIntPresetFunction(int32_t opcode);
7467
int32_t getPresetCount();
7568
void getPreset(int32_t index, aap_preset_t& preset);
7669
int32_t getPresetIndex();

include/aap/core/aapxs/aapxs-runtime.h

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,48 @@ namespace aap::xs {
202202
public:
203203
virtual AAPXSDefinition& asPublic() = 0;
204204
};
205+
206+
class TypedClientAAPXS {
207+
const char* uri;
208+
protected:
209+
AAPXSInitiatorInstance *aapxs_instance;
210+
AAPXSSerializationContext *serialization;
211+
212+
public:
213+
TypedClientAAPXS(const char* uri, AAPXSInitiatorInstance* initiatorInstance, AAPXSSerializationContext* serialization)
214+
: uri(uri), aapxs_instance(initiatorInstance), serialization(serialization) {
215+
}
216+
217+
virtual ~TypedClientAAPXS() {}
218+
219+
// This must be visible to consuming code i.e. defined in this header file.
220+
template<typename T>
221+
static void getTypedCallback(void* callbackContext, AndroidAudioPlugin* plugin, int32_t requestId) {
222+
auto callbackData = (WithPromise<TypedClientAAPXS, T>*) callbackContext;
223+
auto thiz = (TypedClientAAPXS*) callbackData->context;
224+
T result = *(T*) (thiz->serialization->data);
225+
callbackData->promise->set_value(result);
226+
}
227+
228+
// This must be visible to consuming code i.e. defined in this header file.
229+
// FIXME: use spinlock for RT-safe extension functions, which means there should be another RT-safe version of this function.
230+
template<typename T>
231+
T callTypedFunctionSynchronously(int32_t opcode) {
232+
std::promise<T> promise{};
233+
uint32_t requestId = aapxs_instance->get_new_request_id(aapxs_instance);
234+
auto future = promise.get_future();
235+
WithPromise<TypedClientAAPXS, T> callbackData{this, &promise};
236+
AAPXSRequestContext request{getTypedCallback<int32_t>, &callbackData, serialization, uri, requestId, opcode};
237+
238+
aapxs_instance->send_aapxs_request(aapxs_instance, &request);
239+
240+
future.wait();
241+
return future.get();
242+
}
243+
244+
static void getVoidCallback(void* callbackContext, AndroidAudioPlugin* plugin, int32_t requestId);
245+
void callVoidFunctionSynchronously(int32_t opcode);
246+
};
205247
}
206248

207249
#endif //AAP_CORE_AAPXS_RUNTIME_H

0 commit comments

Comments
 (0)