* wxCreateDynamicObject() uses an hashtable now

* wxClassInfo::first = NULL after the hashtable is initialized
* dynlib has been simplified.
* Some fix in the serialization core and in wxObject::StoreObject()/LoadObject()
* Updates in utils/serialize/sermain.cpp


git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@645 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Guilhem Lavaux
1998-09-01 17:17:05 +00:00
parent 2f6407b947
commit f4a8c29f7a
13 changed files with 157 additions and 259 deletions

View File

@@ -8,52 +8,18 @@
#include <wx/string.h>
#include <wx/list.h>
#include <wx/dynarray.h>
// ---------------------------------------------------------------------------
// Some more info on a class
typedef struct {
wxClassInfo *class_info;
wxString path;
} wxClassLibInfo;
// ---------------------------------------------------------------------------
// Useful arrays
WX_DEFINE_ARRAY(wxClassInfo *, wxArrayClassInfo);
WX_DEFINE_ARRAY(wxClassLibInfo *, wxArrayClassLibInfo);
// ---------------------------------------------------------------------------
// wxClassLibrary
class wxClassLibrary {
protected:
wxArrayClassLibInfo m_list;
public:
wxClassLibrary(void);
~wxClassLibrary(void);
// Dynamic (un)register a (new) class in the database
void RegisterClass(wxClassInfo *class_info, const wxString& path);
void UnregisterClass(wxClassInfo *class_info);
// Fetch all infos whose name matches the string (wildcards allowed)
bool FetchInfos(const wxString& path, wxArrayClassLibInfo& infos);
// Create all objects whose name matches the string (wildcards allowed)
bool CreateObjects(const wxString& path, wxArrayClassInfo& objs);
// Create one object using the EXACT name
wxObject *CreateObject(const wxString& path);
};
#include <wx/hash.h>
// ---------------------------------------------------------------------------
// wxLibrary
class wxLibrary: public wxObject {
protected:
wxClassLibrary *m_liblist;
void *m_handle;
bool m_destroy;
public:
wxHashTable classTable;
public:
wxLibrary(void *handle);
~wxLibrary(void);
@@ -64,7 +30,12 @@ public:
// Create the object whose classname is "name"
wxObject *CreateObject(const wxString& name);
wxClassLibrary *ClassLib() const;
// Merge the symbols with the main symbols: WARNING! the library will not
// be unloaded.
void MergeWithSystem();
protected:
void PrepareClasses(wxClassInfo **first);
};
// ---------------------------------------------------------------------------
@@ -89,7 +60,10 @@ extern wxLibraries wxTheLibraries;
// ---------------------------------------------------------------------------
// Interesting defines
#define WXDLL_ENTRY_FUNCTION() extern "C" wxClassLibrary *GetClassList()
#define WXDLL_EXIT_FUNCTION(param) extern "C" void FreeClassList(wxClassLibrary *param)
#define WXDLL_ENTRY_FUNCTION() \
extern "C" wxClassInfo **wxGetClassFirst(); \
wxClassInfo **wxGetClassFirst() { \
return &wxClassInfo::first; \
}
#endif

View File

@@ -29,10 +29,12 @@ class WXDLLEXPORT wxObject;
#endif
class WXDLLEXPORT wxClassInfo;
class WXDLLEXPORT ostream;
class WXDLLIMPORT ostream;
class WXDLLEXPORT wxInputStream;
class WXDLLIMPORT wxObjectInputStream;
class WXDLLIMPORT wxObjectOutputStream;
class WXDLLEXPORT wxObjectInputStream;
class WXDLLEXPORT wxObjectOutputStream;
class WXDLLEXPORT wxHashTable;
class WXDLLEXPORT wxObject_Serialize;
/*
* Dynamic object system declarations
@@ -57,6 +59,8 @@ class WXDLLEXPORT wxClassInfo
static wxClassInfo *first;
wxClassInfo *next;
static wxHashTable classTable;
wxClassInfo(char *cName, char *baseName1, char *baseName2, int sz, wxObjectConstructorFn fn);
wxObject *CreateObject(void);
@@ -195,6 +199,9 @@ class WXDLLEXPORT wxObject
protected:
wxObjectRefData *m_refData;
#ifdef USE_STORABLE_CLASSES
wxObject_Serialize *m_serialObj;
#endif
};
/*

View File

@@ -65,6 +65,10 @@
#include "wx/dirdlg.h"
#include "wx/cmndata.h"
#include "wx/intl.h"
#ifdef USE_STORABLE_CLASSES
#include "wx/objstrm.h"
#include "wx/serbase.h"
#endif
#endif
// _WX_WXH__

View File

@@ -42,27 +42,22 @@ wxLibraries wxTheLibraries;
wxLibrary::wxLibrary(void *handle)
{
typedef wxClassLibrary *(*t_get_list)(void);
t_get_list get_list;
typedef wxClassInfo **(*t_get_first)(void);
t_get_first get_first;
m_handle = handle;
m_destroy = TRUE;
get_list = (t_get_list)GetSymbol("GetClassList");
m_liblist = (*get_list)();
// Some system may use a local heap for library.
get_first = (t_get_first)GetSymbol("wxGetClassFirst");
// It is a wxWindows DLL.
if (get_first)
PrepareClasses(get_first());
}
wxLibrary::~wxLibrary()
{
if (m_handle) {
typedef void (*t_free_list)(wxClassLibrary *);
t_free_list free_list;
free_list = (t_free_list) GetSymbol("FreeClassList");
if (free_list != NULL)
free_list(m_liblist);
else
delete m_liblist;
if (m_handle && m_destroy) {
#ifdef __UNIX__
dlclose(m_handle);
#endif
@@ -74,7 +69,36 @@ wxLibrary::~wxLibrary()
wxObject *wxLibrary::CreateObject(const wxString& name)
{
return m_liblist->CreateObject(name);
wxClassInfo *info = (wxClassInfo *)classTable.Get(name);
if (!info)
return NULL;
return info->CreateObject();
}
void wxLibrary::PrepareClasses(wxClassInfo **first)
{
// Index all class infos by their class name
wxClassInfo *info = *first;
while (info)
{
if (info->className)
classTable.Put(info->className, (wxObject *)info);
info = info->next;
}
// Set base pointers for each wxClassInfo
info = *first;
while (info)
{
if (info->GetBaseClassName1())
info->baseInfo1 = (wxClassInfo *)classTable.Get(info->GetBaseClassName1());
if (info->GetBaseClassName2())
info->baseInfo2 = (wxClassInfo *)classTable.Get(info->GetBaseClassName2());
info = info->next;
}
*first = NULL;
}
void *wxLibrary::GetSymbol(const wxString& symbname)
@@ -117,7 +141,7 @@ wxLibrary *wxLibraries::LoadLibrary(const wxString& name)
if ( (node = m_loaded.Find(name.GetData())) )
return ((wxLibrary *)node->Data());
#ifdef __UNIX__
#if defined(__UNIX__)
lib_name.Prepend("./lib");
lib_name += ".so";
@@ -127,14 +151,16 @@ wxLibrary *wxLibraries::LoadLibrary(const wxString& name)
if (!handle)
return NULL;
#endif
#ifdef __WINDOWS__
#elif defined(__WINDOWS__)
lib_name += ".dll";
HMODULE handle = LoadLibrary(lib_name);
if (!handle)
return NULL;
#else
return NULL;
#endif
lib = new wxLibrary((void *)handle);
m_loaded.Append(name.GetData(), lib);
@@ -155,90 +181,3 @@ wxObject *wxLibraries::CreateObject(const wxString& path)
}
return NULL;
}
// ---------------------------------------------------------------------------
// wxClassLibrary (this class is used to access the internal class)
// ---------------------------------------------------------------------------
wxClassLibrary::wxClassLibrary(void)
{
}
wxClassLibrary::~wxClassLibrary(void)
{
size_t i;
for (i=0;i<m_list.Count();i++)
delete (m_list[i]);
}
void wxClassLibrary::RegisterClass(wxClassInfo *class_info,
const wxString& path)
{
wxClassLibInfo *info = new wxClassLibInfo;
info->class_info = class_info;
info->path = path;
m_list.Add(info);
}
void wxClassLibrary::UnregisterClass(wxClassInfo *class_info)
{
size_t i = 0;
while (i < m_list.Count()) {
if (m_list[i]->class_info == class_info) {
delete (m_list[i]);
m_list.Remove(i);
return;
}
i++;
}
}
bool wxClassLibrary::CreateObjects(const wxString& path,
wxArrayClassInfo& objs)
{
wxClassLibInfo *info;
size_t i = 0;
while (i < m_list.Count()) {
info = m_list[i];
if (wxMatchWild(path, info->path))
objs.Add(info->class_info);
i++;
}
return (i > 0);
}
bool wxClassLibrary::FetchInfos(const wxString& path,
wxArrayClassLibInfo& infos)
{
wxClassLibInfo *info;
size_t i = 0;
while (i < m_list.Count()) {
info = m_list[i];
if (wxMatchWild(path, info->path)) {
wxClassLibInfo *inf = new wxClassLibInfo;
*inf = *info;
infos.Add(inf);
}
i++;
}
return (i > 0);
}
wxObject *wxClassLibrary::CreateObject(const wxString& path)
{
wxClassLibInfo *info;
size_t i = 0;
while (i < m_list.Count()) {
info = m_list[i];
if (wxMatchWild(path, info->path))
return info->class_info->CreateObject();
i++;
}
return NULL;
}

View File

@@ -785,9 +785,14 @@ bool wxDebugContext::PrintClasses(void)
}
int n = 0;
wxClassInfo *info = wxClassInfo::first;
while (info)
wxNode *node;
wxClassInfo *info;
wxClassInfo::classTable.BeginFind();
node = wxClassInfo::classTable.Next();
while (node)
{
info = (wxClassInfo *)node->Data();
if (info->GetClassName())
{
wxTrace("%s ", info->GetClassName());
@@ -801,7 +806,7 @@ bool wxDebugContext::PrintClasses(void)
else
wxTrace("\n");
}
info = info->next;
node = node->Next();
n ++;
}
wxTrace("\nThere are %d classes derived from wxObject.\n", n);

View File

@@ -21,6 +21,7 @@
#endif
#include "wx/module.h"
#include "wx/hash.h"
IMPLEMENT_CLASS(wxModule, wxObject)
@@ -35,16 +36,21 @@ void wxModule::RegisterModule(wxModule* module)
// and register them.
bool wxModule::RegisterModules(void)
{
wxClassInfo* classInfo = wxClassInfo::first;
while (classInfo)
wxNode *node;
wxClassInfo* classInfo;
wxClassInfo::classTable.BeginFind();
node = wxClassInfo::classTable.Next();
while (node)
{
classInfo = (wxClassInfo *)node->Data();
if ((classInfo != (& (wxModule::classwxModule))) &&
classInfo->IsKindOf(CLASSINFO(wxModule)))
{
wxModule* module = (wxModule*) classInfo->CreateObject();
RegisterModule(module);
}
classInfo = classInfo->next;
node = wxClassInfo::classTable.Next();
}
return TRUE;
}

View File

@@ -22,7 +22,10 @@
#ifndef WX_PRECOMP
#include "wx/hash.h"
#ifdef USE_STORABLE_CLASSES
#include "wx/objstrm.h"
#include "wx/serbase.h"
#endif
#endif
#include <string.h>
@@ -40,6 +43,7 @@
#if !USE_SHARED_LIBRARY
wxClassInfo wxObject::classwxObject((char *) "wxObject", (char *) NULL, (char *) NULL, (int ) sizeof(wxObject), (wxObjectConstructorFn) NULL);
wxClassInfo *wxClassInfo::first = (wxClassInfo *) NULL;
wxHashTable wxClassInfo::classTable(wxKEY_STRING);
#endif
/*
@@ -49,11 +53,18 @@ wxClassInfo *wxClassInfo::first = (wxClassInfo *) NULL;
wxObject::wxObject(void)
{
m_refData = (wxObjectRefData *) NULL;
#ifdef USE_STORABLE_CLASSES
m_serialObj = (wxObject_Serialize *)NULL;
#endif
}
wxObject::~wxObject(void)
{
UnRef();
#ifdef USE_STORABLE_CLASSES
if (m_serialObj)
delete m_serialObj;
#endif
}
/*
@@ -184,14 +195,12 @@ bool wxClassInfo::IsKindOf(wxClassInfo *info)
// Set pointers to base class(es) to speed up IsKindOf
void wxClassInfo::InitializeClasses(void)
{
wxHashTable table(wxKEY_STRING);
// Index all class infos by their class name
wxClassInfo *info = first;
while (info)
{
if (info->className)
table.Put(info->className, (wxObject *)info);
classTable.Put(info->className, (wxObject *)info);
info = info->next;
}
@@ -200,23 +209,23 @@ void wxClassInfo::InitializeClasses(void)
while (info)
{
if (info->GetBaseClassName1())
info->baseInfo1 = (wxClassInfo *)table.Get(info->GetBaseClassName1());
info->baseInfo1 = (wxClassInfo *)classTable.Get(info->GetBaseClassName1());
if (info->GetBaseClassName2())
info->baseInfo2 = (wxClassInfo *)table.Get(info->GetBaseClassName2());
info->baseInfo2 = (wxClassInfo *)classTable.Get(info->GetBaseClassName2());
info = info->next;
}
first = NULL;
}
wxObject *wxCreateDynamicObject(char *name)
{
wxClassInfo *info = wxClassInfo::first;
while (info)
{
if (info->className && strcmp(info->className, name) == 0)
return info->CreateObject();
info = info->next;
}
wxClassInfo *info;
info = (wxClassInfo *)wxClassInfo::classTable.Get(name);
if (!info)
return (wxObject *)NULL;
return info->CreateObject();
}
#ifdef USE_STORABLE_CLASSES
@@ -235,37 +244,15 @@ void wxObject::StoreObject( wxObjectOutputStream& stream )
{
wxString obj_name = wxString(GetClassInfo()->GetClassName()) + "_Serialize";
wxLibrary *lib = wxTheLibraries.LoadLibrary("wxserial");
WXSERIAL(wxObject) *serial;
if (!lib) {
wxMessageBox("Can't load wxSerial dynamic library.", "Alert !");
return;
}
serial = (WXSERIAL(wxObject) *)lib->CreateObject( obj_name );
if (!m_serialObj) {
m_serialObj = (WXSERIAL(wxObject) *)lib->CreateObject( obj_name );
if (!serial) {
wxString message;
message.Printf("Can't find the serialization object (%s) for the object %s",
WXSTRINGCAST obj_name, WXSTRINGCAST GetClassInfo()->GetClassName());
wxMessageBox(message, "Alert !");
return;
}
serial->SetObject(this);
serial->StoreObject(stream);
delete serial;
}
void wxObject::LoadObject( wxObjectInputStream& stream )
{
wxString obj_name = wxString(GetClassInfo()->GetClassName()) + "_Serialize";
wxLibrary *lib = wxTheLibraries.LoadLibrary("wxserial");
WXSERIAL(wxObject) *serial =
(WXSERIAL(wxObject) *)lib->CreateObject( obj_name );
if (!serial) {
if (!m_serialObj) {
wxString message;
message.Printf("Can't find the serialization object (%s) for the object %s",
@@ -274,11 +261,33 @@ void wxObject::LoadObject( wxObjectInputStream& stream )
wxMessageBox(message, "Alert !");
return;
}
m_serialObj->SetObject(this);
}
serial->SetObject(this);
serial->LoadObject(stream);
m_serialObj->StoreObject(stream);
}
delete serial;
void wxObject::LoadObject( wxObjectInputStream& stream )
{
wxString obj_name = wxString(GetClassInfo()->GetClassName()) + "_Serialize";
wxLibrary *lib = wxTheLibraries.LoadLibrary("wxserial");
if (!m_serialObj) {
m_serialObj = (WXSERIAL(wxObject) *)lib->CreateObject( obj_name );
if (!m_serialObj) {
wxString message;
message.Printf("Can't find the serialization object (%s) for the object %s",
WXSTRINGCAST obj_name,
WXSTRINGCAST GetClassInfo()->GetClassName());
wxMessageBox(message, "Alert !");
return;
}
m_serialObj->SetObject(this);
}
m_serialObj->LoadObject(stream);
}
#endif

View File

@@ -49,13 +49,16 @@ void wxObjectOutputStream::WriteObjectDef(wxObjectStreamInfo& info)
if (info.duplicate) {
data_s.WriteString(TAG_DUPLICATE_OBJECT);
data_s.WriteString(GetObjectName(info.object));
printf("info.object (dup %s)\n", info.object->GetClassInfo()->GetClassName());
return;
}
if (info.object) {
data_s.WriteString(info.object->GetClassInfo()->GetClassName());
printf("info.object (%s)\n", info.object->GetClassInfo()->GetClassName());
} else {
data_s.WriteString(TAG_EMPTY_OBJECT);
printf("info.object (NULL)\n");
return;
}
@@ -230,13 +233,13 @@ bool wxObjectInputStream::ReadObjectDef(wxObjectStreamInfo *info)
class_name = data_s.ReadString();
info->children_removed = 0;
info->n_children = 0;
if (class_name == TAG_EMPTY_OBJECT)
info->object = (wxObject *) NULL;
else if (class_name == TAG_DUPLICATE_OBJECT) {
info->object_name = data_s.ReadString();
info->object = SolveName(info->object_name);
info->n_children = 0;
} else {
info->object_name = data_s.ReadString();
info->object = wxCreateDynamicObject( WXSTRINGCAST class_name);

View File

@@ -52,6 +52,8 @@ void wxStreamBuffer::WriteBack(char c)
// Assume that if we write "back" we have read a few bytes: so we have some
// space.
if (m_buffer_pos == m_buffer_start)
return;
m_buffer_pos--;
*m_buffer_pos = c;
@@ -212,6 +214,7 @@ wxInputStream::wxInputStream()
m_i_destroybuf = TRUE;
m_i_streambuf = new wxStreamBuffer(*this);
m_eof = FALSE;
m_lastread = 0;
}
wxInputStream::wxInputStream(wxStreamBuffer *buffer)
@@ -219,6 +222,7 @@ wxInputStream::wxInputStream(wxStreamBuffer *buffer)
m_i_destroybuf = FALSE;
m_i_streambuf = buffer;
m_eof = FALSE;
m_lastread = 0;
}
wxInputStream::~wxInputStream()
@@ -416,12 +420,16 @@ wxOutputStream::wxOutputStream()
{
m_o_destroybuf = TRUE;
m_o_streambuf = new wxStreamBuffer(*this);
m_bad = FALSE;
m_lastwrite = 0;
}
wxOutputStream::wxOutputStream(wxStreamBuffer *buffer)
{
m_o_destroybuf = FALSE;
m_o_streambuf = buffer;
m_bad = FALSE;
m_lastwrite = 0;
}
wxOutputStream::~wxOutputStream()

View File

@@ -172,6 +172,7 @@ const char *wxUserResourceStr = "TEXT";
// Hand-coded IMPLEMENT... macro for wxObject (define static data)
wxClassInfo wxObject::classwxObject((char *) "wxObject", (char *) NULL, (char *) NULL, (int ) sizeof(wxObject), (wxObjectConstructorFn) NULL);
wxClassInfo *wxClassInfo::first = (wxClassInfo *) NULL;
wxHashTable wxClassInfo::classTable(wxKEY_STRING);
#include "wx/button.h"
#include "wx/bmpbuttn.h"

View File

@@ -172,6 +172,7 @@ const char *wxUserResourceStr = "TEXT";
// Hand-coded IMPLEMENT... macro for wxObject (define static data)
wxClassInfo wxObject::classwxObject((char *) "wxObject", (char *) NULL, (char *) NULL, (int ) sizeof(wxObject), (wxObjectConstructorFn) NULL);
wxClassInfo *wxClassInfo::first = (wxClassInfo *) NULL;
wxHashTable wxClassInfo::classTable(wxKEY_STRING);
#include "wx/button.h"
#include "wx/bmpbuttn.h"

View File

@@ -167,6 +167,7 @@ wxPrintPaperDatabase* wxThePrintPaperDatabase = NULL;
// Hand-coded IMPLEMENT... macro for wxObject (define static data)
wxClassInfo wxObject::classwxObject("wxObject", NULL, NULL, sizeof(wxObject), NULL);
wxClassInfo *wxClassInfo::first = NULL;
wxClassInfo wxClassInfo::classTable(wxKEY_STRING);
#include "wx/button.h"
#include "wx/bmpbuttn.h"

View File

@@ -24,64 +24,4 @@
IMPLEMENT_DYNAMIC_CLASS(wxObject_Serialize, wxObject)
#define REGISTER_CLASS(classname) \
lib->RegisterClass(CLASSINFO(classname##_Serialize), #classname "_Serialize")
WXDLL_ENTRY_FUNCTION()
{
wxClassLibrary *lib = new wxClassLibrary;
REGISTER_CLASS(wxList);
REGISTER_CLASS(wxWindow);
REGISTER_CLASS(wxIndividualLayoutConstraint);
REGISTER_CLASS(wxLayoutConstraints);
REGISTER_CLASS(wxFrame);
REGISTER_CLASS(wxPanel);
REGISTER_CLASS(wxDialog);
REGISTER_CLASS(wxMenu);
REGISTER_CLASS(wxMenuItem);
REGISTER_CLASS(wxMenuBar);
REGISTER_CLASS(wxMDIParentFrame);
REGISTER_CLASS(wxMDIChildFrame);
REGISTER_CLASS(wxMDIClientWindow);
REGISTER_CLASS(wxGDIObject);
REGISTER_CLASS(wxBitmap);
REGISTER_CLASS(wxRegion);
REGISTER_CLASS(wxColour);
REGISTER_CLASS(wxFont);
REGISTER_CLASS(wxPen);
REGISTER_CLASS(wxBrush);
REGISTER_CLASS(wxImageList);
REGISTER_CLASS(wxPenList);
REGISTER_CLASS(wxBrushList);
REGISTER_CLASS(wxFontList);
REGISTER_CLASS(wxColourDatabase);
REGISTER_CLASS(wxBitmapList);
REGISTER_CLASS(wxImageList);
REGISTER_CLASS(wxControl);
REGISTER_CLASS(wxSlider);
REGISTER_CLASS(wxCheckBox);
REGISTER_CLASS(wxChoice);
REGISTER_CLASS(wxGauge);
REGISTER_CLASS(wxListBox);
REGISTER_CLASS(wxButton);
REGISTER_CLASS(wxStaticText);
REGISTER_CLASS(wxStaticBox);
REGISTER_CLASS(wxRadioBox);
REGISTER_CLASS(wxComboBox);
REGISTER_CLASS(wxNotebook);
REGISTER_CLASS(wxSplitterWindow);
REGISTER_CLASS(wxGrid);
REGISTER_CLASS(wxGridCell);
return lib;
}
WXDLL_EXIT_FUNCTION(lib)
{
delete lib;
}