archives.cpp Modifiche per far felice la Cinzia
array.*        Corretti copy-constructors dei TPointer_array
assoc.h        Aggiunto virtual al distruttore dei THash_object
defmask.h      Aggiunto DLG_ELABORA
expr.*         Aggiustamenti per compilare a 32 bit
prefix.cpp     Tolta chiusura immediata dei files, vengono lasciati
               aperti il piu' possibile
git-svn-id: svn://10.65.10.50/trunk@6697 c028cbd2-c16b-5b4b-a496-9718f37d4682
			
			
This commit is contained in:
		
							parent
							
								
									cbc5cd8754
								
							
						
					
					
						commit
						80d4350f14
					
				@ -149,29 +149,35 @@ int TArchive::build_restore_list(
 | 
			
		||||
    char floppy,              // @parm Floppy su cui effettuare il backup
 | 
			
		||||
    TString_array& fl) const  // @parm Nomi dei direttori da ripristinare
 | 
			
		||||
{   
 | 
			
		||||
  fl.destroy();
 | 
			
		||||
  if (firm < 0)                                       // Crea lista automaticamente
 | 
			
		||||
  {      
 | 
			
		||||
    TFilename name("a:/backup.ini"); name[0] = floppy;
 | 
			
		||||
    TConfig ini(name);                                                      
 | 
			
		||||
    const int max = ini.list_paragraphs(fl);          // Lista degli archivi
 | 
			
		||||
    for (int i = max-1; i >= 0; i--)
 | 
			
		||||
    TString_array pl;
 | 
			
		||||
    const int max = ini.list_paragraphs(pl);          // Lista degli archivi
 | 
			
		||||
    for (int i = 0; i < max; i++)
 | 
			
		||||
    {
 | 
			
		||||
      const int disk = ini.get_int("Disk", fl.row(i));
 | 
			
		||||
      const TString& name = pl.row(i);
 | 
			
		||||
      const int disk = ini.get_int("Disk", name);
 | 
			
		||||
      if (disk == 1) 
 | 
			
		||||
      {      
 | 
			
		||||
        firm = atol(fl.row(i));
 | 
			
		||||
        fl.add(firm2dir(firm), i);                    // Aggiungi gli archivi che iniziano qui
 | 
			
		||||
      }
 | 
			
		||||
      else fl.destroy(i, TRUE);                       // Elimina gli archivi che non iniziano qui
 | 
			
		||||
    } 
 | 
			
		||||
    
 | 
			
		||||
    name = firm2dir(-1);                              // __ptprf
 | 
			
		||||
    name.add("config");                               // Aggiungi configurazioni
 | 
			
		||||
    fl.add(name);                                                
 | 
			
		||||
        if (name == "config")
 | 
			
		||||
        {
 | 
			
		||||
          TFilename fn(firm2dir(-1));     // __ptprf
 | 
			
		||||
          fn.add(name);                   // Aggiungi configurazioni
 | 
			
		||||
          fl.add(fn);
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
          firm = atol(name);
 | 
			
		||||
          fl.add(firm2dir(firm));         // Aggiungi gli archivi che iniziano qui
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    } 
 | 
			
		||||
  }
 | 
			
		||||
  else  
 | 
			
		||||
  {
 | 
			
		||||
    fl.destroy();
 | 
			
		||||
    fl.add(firm2dir(firm));               // Inserisci solo una ditta (o COM)
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
@ -205,6 +211,19 @@ bool TArchive::fsplit(
 | 
			
		||||
  TString msg("Archiviazione di "); msg << work << " (" << (tot/1024) << "K)";
 | 
			
		||||
  TProgind w(tot, msg, TRUE, TRUE, 40);
 | 
			
		||||
 | 
			
		||||
  if (!os_test_disk_free_space(work, tot))
 | 
			
		||||
  {
 | 
			
		||||
    TString16 dev("A:/*.*"); dev[0] = floppy;
 | 
			
		||||
    TString_array dir;
 | 
			
		||||
    if (list_files(dev, dir) > 0)
 | 
			
		||||
    {
 | 
			
		||||
      warning_box("Il file %s non puo' essere contenuto per intero nel dischetto corrente:\n"
 | 
			
		||||
                  "Accertarsi di aver inserito un dischetto formattato e completamente vuoto prima di continuare.", 
 | 
			
		||||
                  (const char*)from.name());
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  
 | 
			
		||||
  int disk = 0;        
 | 
			
		||||
  TString buffer(BUFSIZE);
 | 
			
		||||
  
 | 
			
		||||
@ -250,14 +269,17 @@ bool TArchive::fsplit(
 | 
			
		||||
          FILE* i = fopen(ini, "w");    // Crea il file backup.ini per evitare messaggi
 | 
			
		||||
          fclose(i);
 | 
			
		||||
        }
 | 
			
		||||
        if (!ok) break;
 | 
			
		||||
        
 | 
			
		||||
        if (ok)
 | 
			
		||||
        {
 | 
			
		||||
          TConfig c(ini, parag);
 | 
			
		||||
          const char* oggi = TDate(TODAY).string();
 | 
			
		||||
        c.set("Size", tot); 
 | 
			
		||||
        c.set("Disk", disk);
 | 
			
		||||
        c.set("Description", desc);
 | 
			
		||||
          c.set("Date", oggi);
 | 
			
		||||
          c.set("Description", desc);
 | 
			
		||||
          c.set("Disk", disk);
 | 
			
		||||
          c.set("Size", tot); 
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
          break;
 | 
			
		||||
        
 | 
			
		||||
        ok = (letti > 0) ? (fwrite((char*)(const char*)buffer, letti, 1, o) == 1) : TRUE;
 | 
			
		||||
        if (!ok) 
 | 
			
		||||
@ -390,13 +412,20 @@ bool TArchive::backup(
 | 
			
		||||
  const TString16 old(prefix().name());
 | 
			
		||||
  prefix().set(NULL);
 | 
			
		||||
  
 | 
			
		||||
  xvt_fsys_save_dir();
 | 
			
		||||
  DIRECTORY curdir; xvt_fsys_get_dir(&curdir);
 | 
			
		||||
  chdir(dir);
 | 
			
		||||
  
 | 
			
		||||
  const TFilename d(dir);
 | 
			
		||||
  const TString16 name(d.name());
 | 
			
		||||
  TFilename work; work.tempdir(); work.add(name); work.ext("gal");
 | 
			
		||||
 | 
			
		||||
  // Cancella eventuali gal residui
 | 
			
		||||
  TString_array gals;
 | 
			
		||||
  list_files("*.gal", gals);
 | 
			
		||||
  list_files("*.000", gals);
 | 
			
		||||
  for (int g = gals.items()-1; g >= 0; g--)
 | 
			
		||||
    ::remove(gals.row(g));
 | 
			
		||||
 | 
			
		||||
  _arc = new ALArchive(work);
 | 
			
		||||
  
 | 
			
		||||
  TString title("Archiviazione di "); title << name;
 | 
			
		||||
@ -418,7 +447,8 @@ bool TArchive::backup(
 | 
			
		||||
  delete _arc; _arc = NULL;
 | 
			
		||||
  
 | 
			
		||||
  remove(work);
 | 
			
		||||
  xvt_fsys_restore_dir();
 | 
			
		||||
  
 | 
			
		||||
  xvt_fsys_set_dir(&curdir);
 | 
			
		||||
  prefix().set(old);
 | 
			
		||||
  
 | 
			
		||||
  return ok;
 | 
			
		||||
@ -534,16 +564,39 @@ bool TArchive::restore(
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool TArchive::restore(long firm, char floppy, bool temp)
 | 
			
		||||
{
 | 
			
		||||
  bool lastdisk = firm >= 0;
 | 
			
		||||
  bool ok = TRUE;
 | 
			
		||||
 | 
			
		||||
  do
 | 
			
		||||
  {
 | 
			
		||||
    TString_array fl;
 | 
			
		||||
    const int num_ditte = build_restore_list(firm, floppy, fl);
 | 
			
		||||
  
 | 
			
		||||
  bool ok = TRUE;
 | 
			
		||||
    for (int f = 0; f < num_ditte; f++)
 | 
			
		||||
    {               
 | 
			
		||||
    ok = restore(fl.row(f), floppy, temp);
 | 
			
		||||
    if (!ok) break;
 | 
			
		||||
      const TToken_string& code = fl.row(f);
 | 
			
		||||
 | 
			
		||||
      ok = restore(code, floppy, temp);
 | 
			
		||||
      if (ok) 
 | 
			
		||||
      {
 | 
			
		||||
        if (!lastdisk)
 | 
			
		||||
          lastdisk = code.find("config") >= 0;
 | 
			
		||||
      }
 | 
			
		||||
      else
 | 
			
		||||
        break;
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (!lastdisk)
 | 
			
		||||
    {                       
 | 
			
		||||
      TFilename cfg("a:/config.001"); cfg[0] = floppy;
 | 
			
		||||
      if (!fexist(cfg))
 | 
			
		||||
        lastdisk = !yesno_box("Si desidera procedere col prossimo disco di ripristino?\n"
 | 
			
		||||
                              "(Rispondere NO se si desidera interrompere la procedura)");
 | 
			
		||||
    }
 | 
			
		||||
  } while(!lastdisk);
 | 
			
		||||
  
 | 
			
		||||
  return ok;  
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -125,15 +125,18 @@ void TArray::resize(
 | 
			
		||||
  //       messaggio di errore.
 | 
			
		||||
 | 
			
		||||
{
 | 
			
		||||
  CHECK(arraysize > size(), "Can't reduce array size.");
 | 
			
		||||
  CHECK(arraysize > _size, "Can't reduce array size.");
 | 
			
		||||
 | 
			
		||||
  TObject** newdata = new TObject* [arraysize];
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
  int i = 0;
 | 
			
		||||
  if (_data != NULL)
 | 
			
		||||
    for (i = 0; i < size(); i++) newdata[i] = _data[i];
 | 
			
		||||
 | 
			
		||||
  while (i < arraysize) newdata[i++] = NULL;
 | 
			
		||||
*/
 | 
			
		||||
  memset(newdata, 0, arraysize*sizeof(TObject*));
 | 
			
		||||
  if (_data != NULL)
 | 
			
		||||
    memcpy(newdata, _data, _size*sizeof(TObject*));
 | 
			
		||||
 | 
			
		||||
  if (_data != NULL) delete _data;
 | 
			
		||||
 | 
			
		||||
@ -228,7 +231,7 @@ TArray::~TArray()
 | 
			
		||||
  if (ok())
 | 
			
		||||
  {
 | 
			
		||||
    destroy();
 | 
			
		||||
    delete _data;
 | 
			
		||||
    delete [] _data;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -605,16 +608,15 @@ bool TPointer_array::destroy(
 | 
			
		||||
  return TArray::destroy(index, pack);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
TPointer_array& TPointer_array::operator=(const TArray& a)
 | 
			
		||||
void TPointer_array::copy(const TArray& a)
 | 
			
		||||
{
 | 
			
		||||
  destroy();
 | 
			
		||||
  if (size() < a.size()) 
 | 
			
		||||
    resize(a.size());
 | 
			
		||||
  
 | 
			
		||||
  for (int i = a.size()-1; i >= 0; i--)
 | 
			
		||||
    add(a[i], i);
 | 
			
		||||
  
 | 
			
		||||
  return *this;
 | 
			
		||||
//  for (int i = a.size()-1; i >= 0; i--)
 | 
			
		||||
//    add(a.objptr(i), i);
 | 
			
		||||
  memcpy(data(), a.data(), a.size() * sizeof(TObject*));
 | 
			
		||||
}              
 | 
			
		||||
 | 
			
		||||
int TPointer_array::add(TObject* object, int index)
 | 
			
		||||
 | 
			
		||||
@ -92,6 +92,8 @@ class TArray : public TContainer
 | 
			
		||||
 | 
			
		||||
// @access:(INTERNAL) Private Member
 | 
			
		||||
{
 | 
			
		||||
  friend class TPointer_array;
 | 
			
		||||
 | 
			
		||||
  // @cmember:(INTERNAL) Array di puntatori ad oggetti
 | 
			
		||||
  TObject** _data;
 | 
			
		||||
  // @cmember:(INTERNAL) Dimensione dell'array
 | 
			
		||||
@ -218,12 +220,16 @@ inline TObject& TArray::operator[] (int index) const
 | 
			
		||||
 | 
			
		||||
class TPointer_array : public TArray
 | 
			
		||||
{
 | 
			
		||||
protected:
 | 
			
		||||
  void copy(const TArray& a);
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
  virtual bool destroy(int index = -1, bool pack = FALSE);
 | 
			
		||||
  virtual int add(TObject* object, int index = -1);
 | 
			
		||||
  virtual int add(const TObject& object, int index = -1);
 | 
			
		||||
  virtual int insert(const TObject& object, int index = 0, bool force = FALSE);
 | 
			
		||||
  virtual TPointer_array& operator= (const TArray& a);
 | 
			
		||||
  virtual TPointer_array& operator= (const TArray& a) { copy(a); return *this; }
 | 
			
		||||
  virtual TPointer_array& operator= (const TPointer_array& a) { copy(a); return *this; }
 | 
			
		||||
  
 | 
			
		||||
  long get_long(int index) const { return (long)objptr(index); }
 | 
			
		||||
  int get_int(int index) const { return (int)get_long(index); }
 | 
			
		||||
@ -232,7 +238,8 @@ public:
 | 
			
		||||
  
 | 
			
		||||
  TPointer_array() { }  
 | 
			
		||||
  TPointer_array(int size) : TArray(size) { }
 | 
			
		||||
  TPointer_array(const TArray& a) { *this = a; }
 | 
			
		||||
  TPointer_array(const TArray& a) { copy(a); }
 | 
			
		||||
  TPointer_array(const TPointer_array& a) { copy(a); }
 | 
			
		||||
  virtual ~TPointer_array() { destroy(); }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -39,7 +39,7 @@ public:
 | 
			
		||||
  THash_object(const char* k, TObject* o = NULL) : _key(k), _obj(o)
 | 
			
		||||
  {}
 | 
			
		||||
  // @cmember Distruttore
 | 
			
		||||
  ~THash_object()
 | 
			
		||||
  virtual ~THash_object()
 | 
			
		||||
  { if (_obj != NULL) delete _obj; }
 | 
			
		||||
}; 
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -28,7 +28,7 @@
 | 
			
		||||
#define DLG_PRINT    24 /* TAG del bottone Stampa */
 | 
			
		||||
#define DLG_SETPRINT 25 /* TAG del bottone Imposta Stampa */
 | 
			
		||||
#define DLG_RECALC   26 /* TAG del bottone Ricalcola */
 | 
			
		||||
#define DLG_F8       27 /* TAG del bottone <Ricerca zoom> */
 | 
			
		||||
#define DLG_ELAB     27 /* TAG del bottone <Elabora> */
 | 
			
		||||
#define DLG_FAX      28 /* TAG del bottone <Fax> */
 | 
			
		||||
#define DLG_EMAIL    29 /* TAG del bottone <Posta> */
 | 
			
		||||
#define DLG_USER    100 /* TAG del primo controllo definito dall'utente */
 | 
			
		||||
 | 
			
		||||
@ -227,24 +227,26 @@ TObject* TExpression::dup() const
 | 
			
		||||
  return o;
 | 
			
		||||
}    
 | 
			
		||||
 | 
			
		||||
TExpression::operator const real&()
 | 
			
		||||
const real& TExpression::as_real()
 | 
			
		||||
{            
 | 
			
		||||
  if (user_func_dirty() || _dirty) eval();
 | 
			
		||||
  if (user_func_dirty() || _dirty) 
 | 
			
		||||
    eval();
 | 
			
		||||
  _dirty = FALSE;
 | 
			
		||||
  return _val.number();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
TExpression::operator const char*()
 | 
			
		||||
const TString& TExpression::as_string()
 | 
			
		||||
{
 | 
			
		||||
  if (user_func_dirty() || _dirty) eval();
 | 
			
		||||
  if (user_func_dirty() || _dirty) 
 | 
			
		||||
    eval();
 | 
			
		||||
  _dirty = FALSE;
 | 
			
		||||
  return _val.string();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
TExpression::operator bool()
 | 
			
		||||
bool TExpression::as_bool()
 | 
			
		||||
{
 | 
			
		||||
  if (user_func_dirty() || _dirty) eval();
 | 
			
		||||
  if (user_func_dirty() || _dirty) 
 | 
			
		||||
    eval();
 | 
			
		||||
  _dirty = FALSE;
 | 
			
		||||
  return !_val.number().is_zero();          
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -443,12 +443,20 @@ protected: // TObject
 | 
			
		||||
public:
 | 
			
		||||
  // @cmember Duplica l'espressione
 | 
			
		||||
  virtual TObject* dup() const;
 | 
			
		||||
  // @cmember operator const | real& | | Ritorna il valore real dell'espressione
 | 
			
		||||
  operator const real&();
 | 
			
		||||
  // @cmember operator const | char* | | Ritorna il valore dell'espressione come stringa
 | 
			
		||||
  operator const char*();
 | 
			
		||||
 | 
			
		||||
  // @cmember Ritorna il valore real dell'espressione
 | 
			
		||||
  const real& as_real();
 | 
			
		||||
  // @cmember Ritorna il valore stringa dell'espressione
 | 
			
		||||
  const TString& as_string();
 | 
			
		||||
  // @cmember Ritorna il valore dell'espressione come booleano
 | 
			
		||||
  operator bool();
 | 
			
		||||
  bool as_bool();
 | 
			
		||||
 | 
			
		||||
  // @cmember operator const | real& | | Ritorna il valore real dell'espressione
 | 
			
		||||
  operator const real&() { return as_real(); }
 | 
			
		||||
  // @cmember operator const | char* | | Ritorna il valore dell'espressione come stringa
 | 
			
		||||
  operator const char*() { return as_string(); }
 | 
			
		||||
  // @cmember Ritorna il valore dell'espressione come booleano
 | 
			
		||||
  operator bool() { return as_bool(); }
 | 
			
		||||
  // @cmember Ritorna il nome della variabile di posto <p varnum>
 | 
			
		||||
  const char* varname(int varnum) const
 | 
			
		||||
  { return _var.varname(varnum); }
 | 
			
		||||
 | 
			
		||||
@ -322,6 +322,7 @@ int TFile_info::close_low()
 | 
			
		||||
    DB_close(_handle);
 | 
			
		||||
    _handle = -1;
 | 
			
		||||
    _last_key = -1;
 | 
			
		||||
    _exclusive = _locked = FALSE;
 | 
			
		||||
  }
 | 
			
		||||
  else
 | 
			
		||||
  {
 | 
			
		||||
@ -341,6 +342,7 @@ int TFile_info::open(bool exclusive, bool index)
 | 
			
		||||
    if (_ref_count > 0 || is_open())  
 | 
			
		||||
    {
 | 
			
		||||
#ifdef DBG            
 | 
			
		||||
      if (_ref_count > 0)
 | 
			
		||||
        NFCHECK("Can't reopen file %d exclusively", _num);
 | 
			
		||||
#endif
 | 
			
		||||
      close_low();
 | 
			
		||||
@ -361,9 +363,12 @@ int TFile_info::close()
 | 
			
		||||
    if (_ref_count == 0)
 | 
			
		||||
    {
 | 
			
		||||
      if (is_open()) 
 | 
			
		||||
      {
 | 
			
		||||
        // Chiudi fisicamente solo se necessario
 | 
			
		||||
        if (_locked || _exclusive)
 | 
			
		||||
          err = close_low();
 | 
			
		||||
      }  
 | 
			
		||||
      _locked = _exclusive = FALSE;
 | 
			
		||||
      _last_key = -1;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  else
 | 
			
		||||
@ -373,7 +378,7 @@ int TFile_info::close()
 | 
			
		||||
 | 
			
		||||
void TFile_info::auto_close()
 | 
			
		||||
{
 | 
			
		||||
  const bool yes = is_open() && !is_locked() && !is_exclusive();
 | 
			
		||||
  const bool yes = is_open() && !(is_locked() || is_exclusive());
 | 
			
		||||
  if (yes)
 | 
			
		||||
    close_low();
 | 
			
		||||
  else
 | 
			
		||||
@ -688,29 +693,16 @@ int TFile_manager::close_closeable()
 | 
			
		||||
  for (TIsam_handle n = _fileinfo.last(); n > 0; n = _fileinfo.pred(n))
 | 
			
		||||
  {
 | 
			
		||||
    TFile_info& i = fileinfo(n);
 | 
			
		||||
    if (i.ref_count() > 0)
 | 
			
		||||
    {
 | 
			
		||||
    if (i.is_open())
 | 
			
		||||
    {
 | 
			
		||||
        if (!i.is_locked() && !i.is_exclusive())
 | 
			
		||||
      if (!(i.is_locked() || i.is_exclusive()))
 | 
			
		||||
        i.auto_close();
 | 
			
		||||
      else
 | 
			
		||||
        _open_files++;
 | 
			
		||||
    }
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
#ifdef DBG
 | 
			
		||||
      if (i.is_open())
 | 
			
		||||
      {
 | 
			
		||||
        NFCHECK("File %d is open without references?", i.num());
 | 
			
		||||
        _open_files++;
 | 
			
		||||
      }
 | 
			
		||||
      else
 | 
			
		||||
#endif
 | 
			
		||||
    if (i.ref_count() <= 0)
 | 
			
		||||
      _fileinfo.destroy(n);
 | 
			
		||||
  }
 | 
			
		||||
  }
 | 
			
		||||
  return _open_files;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -814,6 +806,7 @@ void TPrefix::set(
 | 
			
		||||
{                 
 | 
			
		||||
  if (name == NULL)
 | 
			
		||||
  {
 | 
			
		||||
    close_closeable_isamfiles();
 | 
			
		||||
    CCloseDir(NORDIR);
 | 
			
		||||
    CCloseDir(COMDIR);
 | 
			
		||||
    CCloseRecDir(NORDIR);
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										81
									
								
								include/spies.cpp
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										81
									
								
								include/spies.cpp
									
									
									
									
									
										Executable file
									
								
							@ -0,0 +1,81 @@
 | 
			
		||||
#include <spies.h>
 | 
			
		||||
 | 
			
		||||
///////////////////////////////////////////////////////////
 | 
			
		||||
// TSpy_target
 | 
			
		||||
///////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
void TSpy_target::notify(TSpy_message msg, void* pJolly)
 | 
			
		||||
{
 | 
			
		||||
  for (int i = _spies.last(); i >= 0; i = _spies.pred(i))
 | 
			
		||||
  {
 | 
			
		||||
    TSpy* spy = (TSpy*)_spies.objptr(i);
 | 
			
		||||
    spy->notify(msg, pJolly);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool TSpy_target::add_spy(TSpy* spy)
 | 
			
		||||
{
 | 
			
		||||
#ifdef DBG
 | 
			
		||||
  for (int i = _spies.last(); i >= 0; i--)
 | 
			
		||||
  {
 | 
			
		||||
    TSpy* s = (TSpy*)_spies.objptr(i);
 | 
			
		||||
    if (s == spy)
 | 
			
		||||
    {
 | 
			
		||||
      NFCHECK("Double spy");
 | 
			
		||||
      return FALSE;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
#endif
 | 
			
		||||
  _spies.add(spy);
 | 
			
		||||
  return TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool TSpy_target::kill_spy(const TSpy* spy)
 | 
			
		||||
{
 | 
			
		||||
  for (int i = _spies.last(); i >= 0; i--)
 | 
			
		||||
  {
 | 
			
		||||
    TSpy* s = (TSpy*)_spies.objptr(i);
 | 
			
		||||
    if (s == spy)
 | 
			
		||||
    {
 | 
			
		||||
      _spies.destroy(i, TRUE);
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
#ifdef DBG
 | 
			
		||||
  if (i < 0)
 | 
			
		||||
    NFCHECK("Spy not found");
 | 
			
		||||
#endif
 | 
			
		||||
  return i >= 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
TSpy_target::~TSpy_target()
 | 
			
		||||
{
 | 
			
		||||
  notify(spy_delete, NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
///////////////////////////////////////////////////////////
 | 
			
		||||
// TSpy
 | 
			
		||||
///////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
void TSpy::spy(TSpy_target* t)
 | 
			
		||||
{
 | 
			
		||||
  if (_target)
 | 
			
		||||
    _target->kill_spy(this);
 | 
			
		||||
  _target = t;
 | 
			
		||||
  if (_target)
 | 
			
		||||
    _target->add_spy(this);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void TSpy::notify(TSpy_message msg, void* pJolly)
 | 
			
		||||
{
 | 
			
		||||
  CHECK (_target, "Unemployed spy notified");
 | 
			
		||||
  if (_notify)
 | 
			
		||||
    _notify(*this, msg, pJolly);
 | 
			
		||||
  if (msg == spy_delete)
 | 
			
		||||
    spy(NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
TSpy::~TSpy()
 | 
			
		||||
{
 | 
			
		||||
  spy(NULL);
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										54
									
								
								include/spies.h
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										54
									
								
								include/spies.h
									
									
									
									
									
										Executable file
									
								
							@ -0,0 +1,54 @@
 | 
			
		||||
#ifndef __SPIES_H
 | 
			
		||||
#define __SPIES_H
 | 
			
		||||
 | 
			
		||||
#ifndef __ARRAY_H
 | 
			
		||||
#include <array.h>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
enum TSpy_message { spy_delete, spy_change };
 | 
			
		||||
 | 
			
		||||
class TSpy_target : public TObject
 | 
			
		||||
{
 | 
			
		||||
  friend class TSpy;
 | 
			
		||||
  TPointer_array _spies;
 | 
			
		||||
 | 
			
		||||
protected:
 | 
			
		||||
  bool add_spy(TSpy* spy);
 | 
			
		||||
  bool kill_spy(const TSpy* spy);
 | 
			
		||||
 | 
			
		||||
  void notify(TSpy_message msg, void* hint);
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
  void notify_change(void* hint = NULL) { notify(spy_change, hint); }
 | 
			
		||||
 | 
			
		||||
  TSpy_target() { }
 | 
			
		||||
  virtual ~TSpy_target();
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
typedef void (*SPY_NOTIFY)(TSpy& spy, TSpy_message msg, void* pJolly);
 | 
			
		||||
 | 
			
		||||
class TSpy : public TObject
 | 
			
		||||
{
 | 
			
		||||
  friend class TSpy_target;
 | 
			
		||||
 | 
			
		||||
  TSpy_target* _target;
 | 
			
		||||
  SPY_NOTIFY _notify;
 | 
			
		||||
  bool _dirty;
 | 
			
		||||
 | 
			
		||||
protected:
 | 
			
		||||
  virtual void notify(TSpy_message msg, void* pJolly);
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
  TSpy_target* target_ptr() const { return _target; }
 | 
			
		||||
  TSpy_target& target() const { CHECK(_target, "NULL spy target"); return *_target; }
 | 
			
		||||
 | 
			
		||||
  void spy(TSpy_target* t);
 | 
			
		||||
  void set_notify(SPY_NOTIFY sn) { _notify = sn; }
 | 
			
		||||
  bool dirty() { bool d = _dirty; _dirty = FALSE; return d; }
 | 
			
		||||
 | 
			
		||||
  TSpy() : _target(NULL), _notify(NULL), _dirty(FALSE) { }
 | 
			
		||||
  TSpy(TSpy_target* t) : _target(NULL), _notify(NULL) { spy(t); }
 | 
			
		||||
  virtual ~TSpy();
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif 
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user