Developer forums (C::B DEVELOPMENT STRICTLY!) > Development
SVN 2835: Missing subdirectory "resources" under "src/plugins/contrib/cb_koders"
vesselin_peev:
Yes, it works this way -- I understand they are headers managed by wxSmith, namely:
--- Code: ---//(*Headers(KodersDialog)
#include <wx/button.h>
#include <wx/choice.h>
#include <wx/dialog.h>
#include <wx/intl.h>
#include <wx/settings.h>
#include <wx/sizer.h>
#include <wx/stattext.h>
#include <wx/textctrl.h>
//*)
--- End code ---
and unless there are bugs in wxSmith, they should be all the headers needed for compiling the source file correctly.
As a start, #include <wx/wxprec.h> should be removed from kodersdialog.h. The headers managed by wxSmith should remain there, rather than be moved to kodersdialog.cpp, because first, they do not have to do with precompilation, and second, if kodersdialog.h is used by any other compilation unit, the other compilation unit will not need to include the same headers, avoiding duplication of #include statements.
Of course, their inclusion to be avoided when CB_PRECOMP is defined, the #ifndef CB_PRECOMP block should be put again around those headers. Actually, rather than doing just that, how about the following, to be flexible. Here's how I'd make the beginning of kodersdialog.h (please read the inline comments, too):
--- Code: ---#ifndef KODERSDIALOG_H
#define KODERSDIALOG_H
#if !defined(CB_PRECOMP) && !defined(WX_PRECOMP)
//(*Headers(KodersDialog)
#include <wx/button.h>
#include <wx/choice.h>
#include <wx/dialog.h>
#include <wx/intl.h>
#include <wx/settings.h>
#include <wx/sizer.h>
#include <wx/stattext.h>
#include <wx/textctrl.h>
//*)
#elif !defined(CB_PRECOMP) && defined(WX_PRECOMP)
// Define any WxWidgets headers not included by <wx/wx.h>
// but which may be needed by the current file.
// (When WX_PRECOMP is defined, <wx/wxprec.h>,
// which itself includes <wx/wx.h>, may not include all those.
// When CB_PRECOMP is defined, no inclusion should be made
// because the assumption is that the precompiled header used
// in this case includes all such necessities.
//
// For the current revision (SVN 2840) of
// kodersdialog.cpp and kodersdialog.h,
// nothing should be put here, because
// #include <wx/wxprec.h> would include
// all necessities
// (if WX_PRECOMP is defined, of course).
#endif
--- End code ---
and kodersdialog.cpp:
--- Code: ---#ifdef CB_PRECOMP
#include "sdk.h"
#elif WX_PRECOMP
#include <wx/wxprec.h>
#endif
#ifdef __BORLANDC__
#pragma hdrstop
#endif
#include "kodersdialog.h"
--- End code ---
If you will note in the last quote, when both CB_PRECOMP and WX_PRECOMP are defined, the CB_PRECOMP conditional block is processed only. As far as I know, we cannot have 2 precompiled headers used by a single file, hence the need for conditional compilation when we want to switch between 2.
@MortenMacFly, now I have come to understand the reason why kodersdialog.cpp is not related to the SDK, but, as far as I can see, there is not a different precompiled header from sdk.h used by CodeBlocks (with the exception of wx/wxprec.h but that includes only WxWidgets stuff).
killerbot:
--- Quote ---The headers managed by wxSmith should remain there, rather than be moved to kodersdialog.cpp, because first, they do not have to do with precompilation, and second, if kodersdialog.h is used by any other compilation unit, the other compilation unit will not need to include the same headers, avoiding duplication of #include statements.
--- End quote ---
Not true : have a look at the "C++ coding standards" book from Sutter/Alexandrescu or in other books of Sutter or Meyers, you always want to minimize dependencies.
Example : Morton initially used a wxCombobox, so the Koderdialog.hpp was including that header. Now when wx changes something to that header every client of our header dialog needs to rebuild. What do the clients care about how our dialog was implemented. If the include was just in the cpp file, our file needs to rebuild (since some part of it's implementation changed, or something he depends upon) and the kodersdialog do not need to rebuild.
It is already bad enough that C++ doesn't seperate interface from implementation (when I changed from combobox to a wChoice to avoid a wx bug on linux) the client needed to recompile, and once again they should not, but here's it's the fault of C++.
Look at the PUBLIC interface of the kodersdialog, this is the only part a client will use, there's no sign in there of buttons, choices, text ctrl's or whatever. So avoid 'leaking' that to the outside. And with pointers and references together with forward declarations you can achieve that.
Look at STL for example they provide a special header for that iosfwd, so no need to include in headers the iostream ...
Now let's be silly, and assume there would be some quirky method in the interface that would need let's say a button, a choice, ... And I said quirky, so passing by value (bye bye performance) ;-)
Then your argument says, well I don't need to include anything anymore : not good and dangerous.
1) not good :
maybe I just needed that function with the button and I don't call the choice one --> I do not need that include from choice, no sir, I just asked for a button, no extra choice's or me.
2 dangerous :
- the button and choice were included by the kodersdialog. In "MY" file wich included that kodersdialog, I myself also use a button (just imagine it's some sort of interesting structure or class, let's forget about the gui aspect), BUT I forgot to add the include for the button, I compile. Everything compiles nicely, no not thanks to me, thanks to that kodersdialog !!!
NOTE : I do not call that button method, or switching back to the original case, nothing in the public interface related to buttons.
Nice new version of the kodersdialog (hint : no more buttons in there -> so no include of it in the header), I surely want that. I compile -> error button not known. Why why why, I used to work before, ok time to spend some prescious time to find out, who in the past gave me that include of button --> nice headers traversals to find out. Forget about, correct solution : I include it myself.
Does this sound stupid, maybe, but it's a fact of life, it has happend/happens to all of us. Those gurus I mentioned above, they were willing to spend time, effort and book space to it because it matters.
The client should always include what he needs.
This should be the way :
--- Code: ---#include <wx/button.h>
Button MyButton;
// do something with that button
KodersDialog MyDialog;
MyDialog.MethodUsingAButtonByValue(MyButton);
--- End code ---
And if I would use that choice function also, well I include the stuff needed to be able to use that function.
Cheers.
takeshimiya:
--- Quote from: killerbot on August 13, 2006, 10:44:29 am ---It is already bad enough that C++ doesn't seperate interface from implementation (when I changed from combobox to a wChoice to avoid a wx bug on linux) the client needed to recompile, and once again they should not, but here's it's the fault of C++.
--- End quote ---
And that's when the pImpl idiom comes in handy, right? :):
Normally one would write:
--- Code: (cpp) ---// file x.h
class X {
// public and protected members
private:
// private members; whenever these change, all client code must be recompiled
};
--- End code ---
Using the pImpl paradigm we can write instead:
--- Code: (cpp) ---// file x.h
class X {
// public and protected members
private:
class XImpl* pImpl; // a pointer to a forward-declared class
};
// file x.cpp
struct XImpl
{
// private members; fully hidden, can be changed at will without recompiling clients
};
--- End code ---
There are relatively minor costs involved in performance, so it shouldn't be used without care (there are techniques to almost remove those costs too).
OMGUI, a GUI toolkit in development, relies heavily on this idea and just uses pImpls everywhere, therefore having two big advantages: improve compile speeds (removement of a lot of headers you would normally use for private members), and an ABI and API a lot more stable, perhaps even compatible between major versions (since implementations are way more prone to change than interfaces).
Only time will tell how much performance costs in real-world usage for an entire toolkit being based on this.
But so far, for some critical parts where API/ABI stability and less compile time is desired, like the case of Code::Blocks SDK (cbEditorInternalData* anyone? :P), this proves to be a really helpful paradigm.
mandrav:
We 're already using PIMPL in some places, thanks for the info...
takeshimiya:
--- Quote from: mandrav on August 13, 2006, 12:45:13 pm ---We 're already using PIMPL in some places, thanks for the info...
--- End quote ---
Yup, just adding a bit more of info to the Lieven's informative post.
--- Quote from: Takeshi Miya on August 13, 2006, 12:43:51 pm ---But so far, for some critical parts where API/ABI stability and less compile time is desired, like the case of Code::Blocks SDK (cbEditorInternalData* anyone? :P), this proves to be a really helpful paradigm.
--- End quote ---
:)
Do you think a full conversion of the SDK to the pImpl idiom is desirable? (not much interested about compile speed, but binary compatibility)
Navigation
[0] Message Index
[#] Next page
[*] Previous page
Go to full version