Replace boost::shared_ptr<TextClass> with a global cache of sorts of the TextClass's used by Buffers---or, more strictly, constructed by BufferParams::makeTextClass(). The action is in TextClass.{h,cpp}.

I've left the typedef in TextClassPtr.h. At the moment, it's kind of silly. But I've left it mostly because it helps to identify where the TextClass's stored in the TextClassBundle are used, and maybe it'd be worth having some sort of strong typedef like the one for BaseClassIndex here.

I need to check whether the textClass_ member of InsetCollapsable is needed now. I think not.



git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@23232 a592a061-630c-0410-9148-cb99ea01b6c8
This commit is contained in:
Richard Heck 2008-02-25 19:31:31 +00:00
parent 4d20376360
commit b2475f6625
10 changed files with 104 additions and 32 deletions

View File

@ -1410,7 +1410,7 @@ BaseClassIndex BufferParams::baseClass() const
void BufferParams::makeTextClass()
{
textClass_.reset(new TextClass(baseclasslist[baseClass()]));
textClass_ = TextClassBundle::get().newClass(baseclasslist[baseClass()]);
//FIXME It might be worth loading the children's modules here,
//just as we load their bibliographies and such, instead of just

View File

@ -1875,8 +1875,7 @@ bool LyXFunc::wasMetaKey() const
}
void LyXFunc::updateLayout(TextClassPtr const & oldlayout,
Buffer * buffer)
void LyXFunc::updateLayout(TextClassPtr oldlayout,Buffer * buffer)
{
lyx_view_->message(_("Converting document to new document class..."));

View File

@ -136,7 +136,7 @@ private:
///
bool ensureBufferClean(BufferView * bv);
///
void updateLayout(TextClassPtr const & oldlayout, Buffer * buffer);
void updateLayout(TextClassPtr oldlayout, Buffer * buffer);
};
/// Implementation is in LyX.cpp

View File

@ -640,10 +640,10 @@ void expandFlexInsert(Menu & tomenu, Buffer const * buf, string s)
FuncRequest(LFUN_NOACTION)));
return;
}
InsetLayouts const & insetLayouts =
TextClass::InsetLayouts const & insetLayouts =
buf->params().textClass().insetLayouts();
InsetLayouts::const_iterator cit = insetLayouts.begin();
InsetLayouts::const_iterator end = insetLayouts.end();
TextClass::InsetLayouts::const_iterator cit = insetLayouts.begin();
TextClass::InsetLayouts::const_iterator end = insetLayouts.end();
for (; cit != end; ++cit) {
docstring const label = cit->first;
if (cit->second.lyxtype() == s)

View File

@ -1131,6 +1131,30 @@ bool TextClass::hasTocLevels() const
}
TextClassPtr TextClassBundle::newClass(TextClass const & baseClass)
{
TextClass * tc = new TextClass(baseClass);
tc_list_.push_back(tc);
return tc;
}
TextClassBundle & TextClassBundle::get()
{
static TextClassBundle singleton;
return singleton;
}
TextClassBundle::~TextClassBundle()
{
std::list<TextClassPtr>::iterator it = tc_list_.begin();
std::list<TextClassPtr>::iterator end = tc_list_.end();
for (; it != end; ++it)
delete *it;
}
ostream & operator<<(ostream & os, PageSides p)
{
switch (p) {

View File

@ -14,6 +14,7 @@
#include "FontInfo.h"
#include "LayoutEnums.h"
#include "LayoutPtr.h"
#include "TextClassPtr.h"
#include "insets/InsetLayout.h"
@ -22,9 +23,10 @@
#include <boost/shared_ptr.hpp>
#include <vector>
#include <set>
#include <list>
#include <map>
#include <set>
#include <vector>
namespace lyx {
@ -35,17 +37,34 @@ class Lexer;
class Counters;
class FloatList;
/// List of inset layouts
typedef std::map<docstring, InsetLayout> InsetLayouts;
/// Stores the layout specification of a LyX document class.
/// A TextClass represents a collection of layout information: At the
/// moment, this includes Layout's and InsetLayout's.
///
/// The main function of TextClass objecs is to provide layout information
/// to a Buffer, by being the TextClass associated with the BufferParams for
/// a given Buffer. This is the object returned by BufferParams::textClass().
/// These instances of TextClass do not necessarily correspond just to a
/// *.layout file---that is, to a LyX "document class" or *.layout file---
/// since a Buffer's TextClass, though always based upon a "document class"
/// may be modified by loading modules.
/// That said, some TextClass instances do correspond strictly to document
/// classes, that is, to *.layout files. These instances are known in the code
/// as "base classes". These are cached in BaseClassList.
///
/// Though it does not presently exist, one can imagine an extension of this
/// mechanism that would lead to caching of *.module or *.inc files. In that
/// case, some TextClass's would just correspond to *.module or *.inc files,
/// just as some now correspond to *.layout files.
class TextClass {
public:
/// The individual styles comprising the document class
/// The individual paragraph layouts comprising the document class
typedef std::vector<LayoutPtr> LayoutList;
/// The inset layouts available to this class
typedef std::map<docstring, InsetLayout> InsetLayouts;
/// Construct a layout with default values. Actual values loaded later.
explicit
TextClass(std::string const & = std::string(),
explicit TextClass(std::string const & = std::string(),
std::string const & = std::string(),
std::string const & = std::string(),
bool texClassAvail = false);
@ -90,6 +109,11 @@ public:
/// Sees to that the textclass structure has been loaded
bool load(std::string const & path = std::string()) const;
/// Has this layout file been loaded yet?
/// NOTE This only makes sense when used with "static" TextClass
/// objects, e.g., ones that represent files on disk, as opposed
/// to ones that can be modified by modules.
// FIXME Should we have a modular_ variable, set to true when
// we load a module, that would force false to be returned here?
bool loaded() const { return loaded_; }
/// the list of floats defined in the document class
@ -268,9 +292,39 @@ private:
};
/// This is simply a container for the text classes generated when modules
/// are read, so that they stay in memory for use by Insets, CutAndPaste,
/// and the like. Since they're constructed via new, they wouldn't actually
/// disappear without this class---but this class holds the pointers to them
/// so that they don't leak.
/// FIXME Some sort of garbage collection or reference counting wouldn't
/// be a bad idea here. It might be enough to check when a Buffer is closed
/// (or makeTextClass is called) whether the old TextClass is in use anywhere.
///
/// This is a singleton class. Its sole instance is accessed via
/// TextClassBundle::get().
class TextClassBundle {
public:
/// returns a pointer to a new class equal to baseClass
TextClassPtr newClass(TextClass const & baseClass);
/// Returns the sole instance of this class.
static TextClassBundle & get();
///
~TextClassBundle();
private:
///
std::list<TextClassPtr> tc_list_;
/// control instantiation
TextClassBundle() {};
/// noncopyable
TextClassBundle(TextClassBundle const &);
};
/// convert page sides option to text 1 or 2
std::ostream & operator<<(std::ostream & os, PageSides p);
} // namespace lyx
#endif

View File

@ -6,22 +6,16 @@
*
* Full author contact details are available in file CREDITS.
*/
#ifndef TEXTCLASS_PTR_H
#define TEXTCLASS_PTR_H
#include <boost/shared_ptr.hpp>
namespace lyx {
class TextClass;
/// Global typedef
/** Shared pointer for possibly modular layout. Needed so that paste,
* for example, will still be able to retain the pointer, even when
* the buffer itself is closed.
*/
typedef boost::shared_ptr<TextClass> TextClassPtr;
// This largely useless typedef is scheduled to be replaced by
// something better.
typedef TextClass * TextClassPtr;
} // namespace lyx

View File

@ -132,8 +132,8 @@ void InsetCollapsable::setLayout(BufferParams const & bp)
void InsetCollapsable::setLayout(TextClassPtr tc)
{
textClass_ = tc;
if ( tc.get() != 0 ) {
layout_ = &tc->insetLayout(name());
if ( textClass_ != 0 ) {
layout_ = &textClass_->insetLayout(name());
labelstring_ = layout_->labelstring();
} else {
layout_ = &TextClass::emptyInsetLayout();

View File

@ -42,7 +42,7 @@ public:
InsetCollapsable(
BufferParams const &,
CollapseStatus status = Inset::Open,
TextClassPtr tc = TextClassPtr((TextClass *)0)
TextClassPtr tc = 0
);
///
InsetCollapsable(InsetCollapsable const & rhs);
@ -178,6 +178,7 @@ protected:
private:
/// text class to keep the InsetLayout above in memory
/// FIXME This probably isn't needed now
TextClassPtr textClass_;
/// cache for the layout_. Make sure it is in sync with the text class!
InsetLayout const * layout_;

View File

@ -26,8 +26,8 @@ namespace lyx {
class InsetFlex : public InsetCollapsable {
public:
///
InsetFlex(BufferParams const &,
TextClassPtr tc, string const & layoutName);
InsetFlex(BufferParams const &,TextClassPtr tc,
string const & layoutName);
///
docstring name() const { return from_utf8(name_); }