How to call a function on header inclusion?
up vote
3
down vote
favorite
I'm working on a simple framework for making 2D games. It uses components and systems, which will vary from game to game.
To make it easy for other parts of the engine to loop over all possible systems and / or components, I'd like them to let themselves be known the moment one of them is included (Each has their own header file), in a way creating a list of all possible component types and system types.
I've currently solved this by having a Register struct which is put at the bottom after a system or component definition, passing that component / system pointer as an argument to the constructer of the Register struct, i.e.:
std::vector<Component*> Components
struct Register{
Register(Component* newComponent){
Components.push_back(newComponent);
}
}
Which is then used at the bottom of each component's header:
Register 2DPosReg(&2DPos);
Which makes sure that before we get to our main code all components are listed in Components. In the same fashion I also add the names of these components and some other details to some global vectors.
However, it seems unnecesarily messy to create a temporary object that never gets used just to execute code in it's constructor.
Is there any other way where including the header will make itself 'known' to the rest of the code?
I'd like to avoid my previous solution where I had a long Register(&2DPos, &Vel, &Acc, ...etc) function that would register all options, as any changes to the used components would require re-editing this function.
(Also, first stackoverflow question, apologies if it's long / has beginners mistakes)
c++ game-engine c++17
New contributor
|
show 2 more comments
up vote
3
down vote
favorite
I'm working on a simple framework for making 2D games. It uses components and systems, which will vary from game to game.
To make it easy for other parts of the engine to loop over all possible systems and / or components, I'd like them to let themselves be known the moment one of them is included (Each has their own header file), in a way creating a list of all possible component types and system types.
I've currently solved this by having a Register struct which is put at the bottom after a system or component definition, passing that component / system pointer as an argument to the constructer of the Register struct, i.e.:
std::vector<Component*> Components
struct Register{
Register(Component* newComponent){
Components.push_back(newComponent);
}
}
Which is then used at the bottom of each component's header:
Register 2DPosReg(&2DPos);
Which makes sure that before we get to our main code all components are listed in Components. In the same fashion I also add the names of these components and some other details to some global vectors.
However, it seems unnecesarily messy to create a temporary object that never gets used just to execute code in it's constructor.
Is there any other way where including the header will make itself 'known' to the rest of the code?
I'd like to avoid my previous solution where I had a long Register(&2DPos, &Vel, &Acc, ...etc) function that would register all options, as any changes to the used components would require re-editing this function.
(Also, first stackoverflow question, apologies if it's long / has beginners mistakes)
c++ game-engine c++17
New contributor
IMO your code architecture looks suspicious. What exactly isComponent
in your code? The way it is now it looks like you can only have a single component of each type, which does not seem very useful. Or are you trying to create a type-information like system that only cares about which types of components exist in code?
– UnholySheep
2 days ago
Correct, this only stores information on the possible types of components and systems. Each component has it's own unordered_map where it gets stored based on it's ID.
– Lapin
2 days ago
By the way, no need to apologize. If more first timers put in the effort you've put into phrasing your question, SO would be a better place
– StoryTeller
2 days ago
The unforgettable-factory may be what you want.
– user2709407
2 days ago
1
It is just fine, the 4 or 8 bytes it costs is nothing to worry about. So cheap that you'd consider doing this for each individual component. But it belongs in a .cpp file, not a .h file. Focus a bit on how you package and discover the component. A shared library (aka dll) and either a config list of plugin names or scanning a directory are obvious approaches.
– Hans Passant
2 days ago
|
show 2 more comments
up vote
3
down vote
favorite
up vote
3
down vote
favorite
I'm working on a simple framework for making 2D games. It uses components and systems, which will vary from game to game.
To make it easy for other parts of the engine to loop over all possible systems and / or components, I'd like them to let themselves be known the moment one of them is included (Each has their own header file), in a way creating a list of all possible component types and system types.
I've currently solved this by having a Register struct which is put at the bottom after a system or component definition, passing that component / system pointer as an argument to the constructer of the Register struct, i.e.:
std::vector<Component*> Components
struct Register{
Register(Component* newComponent){
Components.push_back(newComponent);
}
}
Which is then used at the bottom of each component's header:
Register 2DPosReg(&2DPos);
Which makes sure that before we get to our main code all components are listed in Components. In the same fashion I also add the names of these components and some other details to some global vectors.
However, it seems unnecesarily messy to create a temporary object that never gets used just to execute code in it's constructor.
Is there any other way where including the header will make itself 'known' to the rest of the code?
I'd like to avoid my previous solution where I had a long Register(&2DPos, &Vel, &Acc, ...etc) function that would register all options, as any changes to the used components would require re-editing this function.
(Also, first stackoverflow question, apologies if it's long / has beginners mistakes)
c++ game-engine c++17
New contributor
I'm working on a simple framework for making 2D games. It uses components and systems, which will vary from game to game.
To make it easy for other parts of the engine to loop over all possible systems and / or components, I'd like them to let themselves be known the moment one of them is included (Each has their own header file), in a way creating a list of all possible component types and system types.
I've currently solved this by having a Register struct which is put at the bottom after a system or component definition, passing that component / system pointer as an argument to the constructer of the Register struct, i.e.:
std::vector<Component*> Components
struct Register{
Register(Component* newComponent){
Components.push_back(newComponent);
}
}
Which is then used at the bottom of each component's header:
Register 2DPosReg(&2DPos);
Which makes sure that before we get to our main code all components are listed in Components. In the same fashion I also add the names of these components and some other details to some global vectors.
However, it seems unnecesarily messy to create a temporary object that never gets used just to execute code in it's constructor.
Is there any other way where including the header will make itself 'known' to the rest of the code?
I'd like to avoid my previous solution where I had a long Register(&2DPos, &Vel, &Acc, ...etc) function that would register all options, as any changes to the used components would require re-editing this function.
(Also, first stackoverflow question, apologies if it's long / has beginners mistakes)
c++ game-engine c++17
c++ game-engine c++17
New contributor
New contributor
edited 2 days ago
New contributor
asked 2 days ago
Lapin
185
185
New contributor
New contributor
IMO your code architecture looks suspicious. What exactly isComponent
in your code? The way it is now it looks like you can only have a single component of each type, which does not seem very useful. Or are you trying to create a type-information like system that only cares about which types of components exist in code?
– UnholySheep
2 days ago
Correct, this only stores information on the possible types of components and systems. Each component has it's own unordered_map where it gets stored based on it's ID.
– Lapin
2 days ago
By the way, no need to apologize. If more first timers put in the effort you've put into phrasing your question, SO would be a better place
– StoryTeller
2 days ago
The unforgettable-factory may be what you want.
– user2709407
2 days ago
1
It is just fine, the 4 or 8 bytes it costs is nothing to worry about. So cheap that you'd consider doing this for each individual component. But it belongs in a .cpp file, not a .h file. Focus a bit on how you package and discover the component. A shared library (aka dll) and either a config list of plugin names or scanning a directory are obvious approaches.
– Hans Passant
2 days ago
|
show 2 more comments
IMO your code architecture looks suspicious. What exactly isComponent
in your code? The way it is now it looks like you can only have a single component of each type, which does not seem very useful. Or are you trying to create a type-information like system that only cares about which types of components exist in code?
– UnholySheep
2 days ago
Correct, this only stores information on the possible types of components and systems. Each component has it's own unordered_map where it gets stored based on it's ID.
– Lapin
2 days ago
By the way, no need to apologize. If more first timers put in the effort you've put into phrasing your question, SO would be a better place
– StoryTeller
2 days ago
The unforgettable-factory may be what you want.
– user2709407
2 days ago
1
It is just fine, the 4 or 8 bytes it costs is nothing to worry about. So cheap that you'd consider doing this for each individual component. But it belongs in a .cpp file, not a .h file. Focus a bit on how you package and discover the component. A shared library (aka dll) and either a config list of plugin names or scanning a directory are obvious approaches.
– Hans Passant
2 days ago
IMO your code architecture looks suspicious. What exactly is
Component
in your code? The way it is now it looks like you can only have a single component of each type, which does not seem very useful. Or are you trying to create a type-information like system that only cares about which types of components exist in code?– UnholySheep
2 days ago
IMO your code architecture looks suspicious. What exactly is
Component
in your code? The way it is now it looks like you can only have a single component of each type, which does not seem very useful. Or are you trying to create a type-information like system that only cares about which types of components exist in code?– UnholySheep
2 days ago
Correct, this only stores information on the possible types of components and systems. Each component has it's own unordered_map where it gets stored based on it's ID.
– Lapin
2 days ago
Correct, this only stores information on the possible types of components and systems. Each component has it's own unordered_map where it gets stored based on it's ID.
– Lapin
2 days ago
By the way, no need to apologize. If more first timers put in the effort you've put into phrasing your question, SO would be a better place
– StoryTeller
2 days ago
By the way, no need to apologize. If more first timers put in the effort you've put into phrasing your question, SO would be a better place
– StoryTeller
2 days ago
The unforgettable-factory may be what you want.
– user2709407
2 days ago
The unforgettable-factory may be what you want.
– user2709407
2 days ago
1
1
It is just fine, the 4 or 8 bytes it costs is nothing to worry about. So cheap that you'd consider doing this for each individual component. But it belongs in a .cpp file, not a .h file. Focus a bit on how you package and discover the component. A shared library (aka dll) and either a config list of plugin names or scanning a directory are obvious approaches.
– Hans Passant
2 days ago
It is just fine, the 4 or 8 bytes it costs is nothing to worry about. So cheap that you'd consider doing this for each individual component. But it belongs in a .cpp file, not a .h file. Focus a bit on how you package and discover the component. A shared library (aka dll) and either a config list of plugin names or scanning a directory are obvious approaches.
– Hans Passant
2 days ago
|
show 2 more comments
1 Answer
1
active
oldest
votes
up vote
4
down vote
accepted
However, it seems unnecesarily messy to create a temporary object that never gets used just to execute code in it's constructor.
You are correct with your assessment of the solution's aesthetic qualities. Unfortunately C++ doesn't have a better mechanism to accomplish what you are after.
After all, even the C++ standard library has to employ this technique when it wants to instrument code for execution after header inclusion.
Though, since you did mark this C++17, and you intended to put the object declaration in a header, you need to make it an inline variable:
inline Register whatevs(...);
It should produce one object per-header file.
Thank you! I did not know about the inline keyword usage in C++17, good to know.
– Lapin
2 days ago
add a comment |
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
4
down vote
accepted
However, it seems unnecesarily messy to create a temporary object that never gets used just to execute code in it's constructor.
You are correct with your assessment of the solution's aesthetic qualities. Unfortunately C++ doesn't have a better mechanism to accomplish what you are after.
After all, even the C++ standard library has to employ this technique when it wants to instrument code for execution after header inclusion.
Though, since you did mark this C++17, and you intended to put the object declaration in a header, you need to make it an inline variable:
inline Register whatevs(...);
It should produce one object per-header file.
Thank you! I did not know about the inline keyword usage in C++17, good to know.
– Lapin
2 days ago
add a comment |
up vote
4
down vote
accepted
However, it seems unnecesarily messy to create a temporary object that never gets used just to execute code in it's constructor.
You are correct with your assessment of the solution's aesthetic qualities. Unfortunately C++ doesn't have a better mechanism to accomplish what you are after.
After all, even the C++ standard library has to employ this technique when it wants to instrument code for execution after header inclusion.
Though, since you did mark this C++17, and you intended to put the object declaration in a header, you need to make it an inline variable:
inline Register whatevs(...);
It should produce one object per-header file.
Thank you! I did not know about the inline keyword usage in C++17, good to know.
– Lapin
2 days ago
add a comment |
up vote
4
down vote
accepted
up vote
4
down vote
accepted
However, it seems unnecesarily messy to create a temporary object that never gets used just to execute code in it's constructor.
You are correct with your assessment of the solution's aesthetic qualities. Unfortunately C++ doesn't have a better mechanism to accomplish what you are after.
After all, even the C++ standard library has to employ this technique when it wants to instrument code for execution after header inclusion.
Though, since you did mark this C++17, and you intended to put the object declaration in a header, you need to make it an inline variable:
inline Register whatevs(...);
It should produce one object per-header file.
However, it seems unnecesarily messy to create a temporary object that never gets used just to execute code in it's constructor.
You are correct with your assessment of the solution's aesthetic qualities. Unfortunately C++ doesn't have a better mechanism to accomplish what you are after.
After all, even the C++ standard library has to employ this technique when it wants to instrument code for execution after header inclusion.
Though, since you did mark this C++17, and you intended to put the object declaration in a header, you need to make it an inline variable:
inline Register whatevs(...);
It should produce one object per-header file.
edited 2 days ago
answered 2 days ago
StoryTeller
87.9k12174243
87.9k12174243
Thank you! I did not know about the inline keyword usage in C++17, good to know.
– Lapin
2 days ago
add a comment |
Thank you! I did not know about the inline keyword usage in C++17, good to know.
– Lapin
2 days ago
Thank you! I did not know about the inline keyword usage in C++17, good to know.
– Lapin
2 days ago
Thank you! I did not know about the inline keyword usage in C++17, good to know.
– Lapin
2 days ago
add a comment |
Lapin is a new contributor. Be nice, and check out our Code of Conduct.
Lapin is a new contributor. Be nice, and check out our Code of Conduct.
Lapin is a new contributor. Be nice, and check out our Code of Conduct.
Lapin is a new contributor. Be nice, and check out our Code of Conduct.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53203937%2fhow-to-call-a-function-on-header-inclusion%23new-answer', 'question_page');
}
);
Post as a guest
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
IMO your code architecture looks suspicious. What exactly is
Component
in your code? The way it is now it looks like you can only have a single component of each type, which does not seem very useful. Or are you trying to create a type-information like system that only cares about which types of components exist in code?– UnholySheep
2 days ago
Correct, this only stores information on the possible types of components and systems. Each component has it's own unordered_map where it gets stored based on it's ID.
– Lapin
2 days ago
By the way, no need to apologize. If more first timers put in the effort you've put into phrasing your question, SO would be a better place
– StoryTeller
2 days ago
The unforgettable-factory may be what you want.
– user2709407
2 days ago
1
It is just fine, the 4 or 8 bytes it costs is nothing to worry about. So cheap that you'd consider doing this for each individual component. But it belongs in a .cpp file, not a .h file. Focus a bit on how you package and discover the component. A shared library (aka dll) and either a config list of plugin names or scanning a directory are obvious approaches.
– Hans Passant
2 days ago