Skip to content

Conversation

@scravy
Copy link
Member

@scravy scravy commented Mar 3, 2019

Fixes #618

Further refactorings possible would be to not have the NAME be required when defining a component. That's left for some upcoming weekends side projects ;-)

Signed-off-by: Julian Fleischer [email protected]

@scravy scravy added the technical debt Cleaning up code which is there for historical reasons label Mar 3, 2019
@scravy scravy added this to the 0.1 milestone Mar 3, 2019
@scravy scravy self-assigned this Mar 3, 2019
@scravy scravy requested review from a team and frolosofsky March 3, 2019 14:51
@scravy scravy added refactoring Changes which clean up code but don't change the user-visible behavior and removed technical debt Cleaning up code which is there for historical reasons labels Mar 3, 2019
@kostyantyn
Copy link
Member

kostyantyn commented Mar 3, 2019

I have a general question. Why do we need macros for injector? What is the critical improvement it gives us that we should go with the macro and preprocessor logic over simple C++ syntax?

What if we had a class, let's say Application (like UnitEInjector now) which in its constructor initializes each component in the same order we have now and in the destructor invokes the delete on each object in the correct order?

pseudo code:

class Application {
public:

Application() {
  m_state_register = new StateRegisterImpl();
  m_state_processor = new StateRegisterImpl(m_state_register);
  // ...
}

~Application() {
  delete m_state_processor;
  delete m_state_register;
}

StateRegister GetStateRegister() { return m_state_register; }
StateProcessor GetStateProcessor() { return m_state_processor; }

private:
  StateRegister *m_state_register;
  StateProcessor *m_state_register;
}

I see that with macro we don't need to write initializer, deinitializer and getter methods so it's an improvement. But having a bit of boilerplate (we don't create new components often, and at the code review we can check that they are initialized properly), we would have a simple C++ syntax.

Then we don't need templated GetCompoment function, we would just call g_application.GetStateProcessor() for instance. Then we don't need Dependency<...> alias, we will direcrly use * or unique_ptr or whatever the reference is.

@scravy
Copy link
Member Author

scravy commented Mar 3, 2019

Can you please open an issue about this if you feel strongly about this instead of polluting pull requests with your agenda?

@scravy
Copy link
Member Author

scravy commented Mar 3, 2019

Thank you for the thumbs up, despite my rude tone. I copied the comment to an issue and commented there: #723

Copy link
Member

@Gnappuraz Gnappuraz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

utACK 6764600

@frolosofsky
Copy link
Member

I also started work on fixing #618. I thought to come up with complete replacement of NAMEs in the injector, but let's start from GetComponent. You can find my approach to fix this issue in #726.

@scravy
Copy link
Member Author

scravy commented Mar 4, 2019

On the one hand, I like this because it makes easier to reason about types, not only to us, but also to the IDEs & static analysis tools. On the other, I'm unsure about what other benefits it provides over the current code.

@castarco is that a thumbs up or a thumbs down or a I don't know, I'm undecided?

I also started work on fixing #618. I thought to come up with complete replacement of NAMEs in the injector, but let's start from GetComponent. You can find my approach to fix this issue in #726.

I looked at #726. What I like about my version better is that if you do GetComponent<X> where X is not actually defined in the injector, it will not compile. In #726 it throws this UnknownComponentError. I strictly like things which error out on compile time already better.

@frolosofsky
Copy link
Member

frolosofsky commented Mar 4, 2019

I looked at #726. What I like about my version better is that if you do GetComponent where X is not actually defined in the injector, it will not compile. In #726 it throws this UnknownComponentError. I strictly like things which error out on compile time already better.

Yes, until we have runtime-only container for holding components, it's a runtime check. Basically, what I don't like in this PR is a nullptr-casting magic, especially on the API level (see gathering Settings in the walletextention).

@castarco
Copy link

castarco commented Mar 4, 2019

@castarco is that a thumbs up or a thumbs down or a I don't know, I'm undecided?

@scravy mostly a thumbs up, I was just curious about what reasons are behind this change beyond what I could grasp.

Copy link
Member

@AM5800 AM5800 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

utACK 6764600
For me killer feature of this PR compared to #726 is compile error on unknown component. How this is achieved/implemented is not so important

@scravy
Copy link
Member Author

scravy commented Mar 4, 2019

especially on the API level

That API is not exactly public. I can make it private and befriend GetComponent though to make that clear.

I don't like in this PR is a nullptr-casting magic

Happens all the time, you weren't exactly bothered by this in std::enable_if<...static_cast<T *>(nullptr)->ToString()>>. It's an internal trick to select the right method using overloading. I would have used a template specialization but these are not allowed inside classes for historical reasons.

Yes, until we have runtime-only container for holding components

I don't get that and I'm not sure I want that.

@scravy
Copy link
Member Author

scravy commented Mar 4, 2019

Another thing I like better in here is that getting a component is constant, whereas in #726 needs to look it up in a tree map.

@scravy scravy force-pushed the get-component-by-type branch from 6764600 to 9569d3d Compare March 4, 2019 19:30
@scravy scravy requested a review from Ruteri March 4, 2019 19:31
@scravy
Copy link
Member Author

scravy commented Mar 4, 2019

@castarco is that a thumbs up or a thumbs down or a I don't know, I'm undecided?

@scravy mostly a thumbs up, I was just curious about what reasons are behind this change beyond what I could grasp.

Thanks :-) – There's a detailed discussion also about this whole thing in #723, feel free to chime in there!

@frolosofsky
Copy link
Member

That API is not exactly public. I can make it private and befriend GetComponent though to make that clear.

Happens all the time, you weren't exactly bothered by this in std::enable_if<...static_cast<T *>(nullptr)->ToString()>>. It's an internal trick to select the right method using overloading. I would have used a template specialization but these are not allowed inside classes for historical reasons.

I complained about the first version where Get(T*) was a public API. Now it looks great.

Copy link
Member

@frolosofsky frolosofsky left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

utACK 77f0ca1

Signed-off-by: Julian Fleischer <[email protected]>
@scravy scravy force-pushed the get-component-by-type branch from aecc5cc to 420d86f Compare March 4, 2019 21:00
Signed-off-by: Julian Fleischer <[email protected]>
@scravy scravy merged commit 85f9080 into dtr-org:master Mar 4, 2019
@scravy scravy deleted the get-component-by-type branch March 13, 2019 14:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

refactoring Changes which clean up code but don't change the user-visible behavior

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants