Reputation: 1479
I'm using this lib to embed some resource files into an executable.
The resources can be accessed by the macro function LOAD_RESOURCE.
The resources I want to embed:
Loading the common resources is easy:
Resource res1 = LOAD_RESOURCE(resource_my_resource1_xml);
Resource res2 = LOAD_RESOURCE(resource_my_resource2_xml);
My problem is that I only know the type
at runtime, so how can I load resources 3 and 4?
My current solution is through a switch case:
Resource res3, res4;
switch (type)
{
default:
case 1:
res3 = LOAD_RESOURCE(resource_type1_my_resource3_xml);
res4 = LOAD_RESOURCE(resource_type1_my_resource4_xml);
break;
case 2:
res3 = LOAD_RESOURCE(resource_type2_my_resource3_xml);
res4 = LOAD_RESOURCE(resource_type2_my_resource4_xml);
break;
}
However, this isn't very efficient nor pretty when I have N types and N resources for each.
Is there a better alternative? Can I somehow pass a string to the macro function as the argument? Something like LOAD_RESOURCE("resource_type" + type + "_my_resourceN_xml")
?
Upvotes: 0
Views: 414
Reputation: 123431
Can I somehow pass a string to the macro function as the argument?
No you cannot. Macros are expanded by the preprocessor before the compiler actually gets to see the code. In a nutshell, macros are about textual replacment not more.
My problem is that I only know the type at runtime, so how can I load resources 3 and 4?
I don't know the library, but the Resource
is merely a pointer to data and a data length. "Loading" a resource does not more than providing you a handle to it. Hence I would load all resoures on program start and then access them at runtime as needed.
For the sake of the example, lets say this is the library code
#define LOAD_RESOURCE(path) ([](){ return Resource{}; })()
struct Resource {};
Then I would perhaps use this:
#include <map>
#include <utility>
using key = std::pair<int,int>;
std::map<key,Resource> load_all_resources(){
return {
{ {1,1} , LOAD_RESOURCE(resource_type1_my_resource1_xml) },
{ {1,2} , LOAD_RESOURCE(resource_type1_my_resource2_xml) }
};
}
int main (){
auto resources = load_all_resources();
auto type = 1;
auto res1 = resources[{type,1}];
}
To make the loading more copy-paste friendly one can use a macro
#define MY_LOAD_RESOURCE(type,N) { {type,N}, LOAD_RESOURCE( resource_type##type##_my_resource##N_xml )}
such that
std::map<key,Resource> load_all_resources(){
return {
MY_LOAD_RESOURCE(1,1),
MY_LOAD_RESOURCE(1,2),
};
}
expands to the same as above. Complete example.
Upvotes: 1