File: persistent.pike

package info (click to toggle)
roxen 1.2beta2-3
  • links: PTS
  • area: contrib
  • in suites: slink
  • size: 16,920 kB
  • ctags: 8,589
  • sloc: ansic: 89,632; asm: 8,431; sh: 2,915; makefile: 1,784; cpp: 377
file content (120 lines) | stat: -rw-r--r-- 2,446 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
/* $Id: persistent.pike,v 1.31 1997/09/15 21:47:03 peter Exp $ */

/*************************************************************,
* PERSIST. An implementation of persistant objects for Pike.  *
* Variables are saved between restarts.                       *
'*************************************************************/

static void _nosave(){}
static function nosave = _nosave;
private static array __id;

void really_save()
{
  if(nosave()) return;

  array res = ({ });
  mixed b;

  if(!__id)
  {
    mixed i = nameof(this_object());
    if(!arrayp(i)) __id=({i});
    else __id = i;
  }

//  perror("really save (%s)\n", __id*":");
  
  string a;
  foreach(persistent_variables(object_program(this_object()),this_object()),a)
    res += ({ ({ a, this_object()[a] }) });
  open_db(__id[0])[__id[1]]=res;
}


/* Public methods! */
static int ___destructed = 0;

public void begone()
{
  remove_call_out(really_save);
  ___destructed=1;
  if(__id) open_db(__id[0])->delete(__id[1]);
  __id=0;
// A nicer destruct. Won't error() if no object.
  call_out(do_destruct,8,this_object());
}

void destroy()
{
  remove_call_out(really_save);
}

static void compat_persist()
{
  string _id;
  _id=(__id[0]+".class/"+__id[1]);


#define COMPAT_DIR "dbm_dir.perdbm/"
  array var;
  mixed tmp;
  catch
  {
    object file;
    if(!(file=open(COMPAT_DIR+_id, "r"))) return 0;
    perror("compat restore ("+ _id +")\n");
    var=decode_value(tmp=file->read(0x7ffffff));
  };

  if(var)
  {
    foreach(var, var) catch {
      this_object()[var[0]] = var[1];
    };
    if(!__id)
    {
      mixed i = nameof(this_object());
      if(!arrayp(i)) __id=({i});
      else __id = i;
    }
    
    open_db(__id[0])[__id[1]]=tmp;
    rm(COMPAT_DIR+_id);
  }
}

nomask public void persist(mixed id)
{
  array err;
  /* No known id. This should not really happend. */
  if(!id)  error("No known id in persist.\n");
  __id = id;

// Restore
  array var;
  var=open_db(__id[0])[__id[1]];
  if(var && sizeof(var))
  {
    foreach(var, var) if(err=catch {
      this_object()[var[0]] = var[1];
    })
      report_error(" When setting "+(var[0])+" in "+(__id*":")+": "+
		   describe_backtrace(err));
  } else
    compat_persist();

  if(functionp(this_object()->persisted))
    this_object()->persisted();
}
  

public void save()
{
  if(nosave()) return;
  if(!___destructed)
  {
    if(zero_type(find_call_out(really_save)))
      call_out(really_save,10);
  }
}