use --WORLD as root of all actions (GC just deletes --WORLD)
[mala.git] / engine / action.c
blob9d8fba1b5a11dc9a7a50473fd83298c6e9ff2974
1 /*
2 action.c - MaLa actions implementation
4 Copyright (C) 2004, Christian Thaeter <chth@gmx.net>
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License version 2 as
8 published by the Free Software Foundation.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, contact me.
19 #include <stdio.h>
21 #include "mala_types.h"
22 #include "strings.h"
23 #include "stringlist.h"
24 #include "actiondesc.h"
25 #include "engine.h"
26 #include "action.h"
30 MalaAction
31 mala_action_new (MalaString name,
32 void * data,
33 MalaParserFunc parser,
34 MalaDataFactory factory,
35 MalaAction parent)
37 MalaAction self;
39 self = malloc (sizeof (mala_action));
40 if (!self)
41 return NULL;
43 self->name = mala_string_copy (name);
44 self->parser = parser;
45 self->factory = factory;
46 self->data = data;
47 self->desc = NULL;
49 LIST_INIT (&self->childs);
51 self->parent = parent;
53 if (parent)
54 LIST_INSERT_HEAD (&parent->childs, self, cldnode);
56 if (name->bucket->gc_trace > MALA_NOTRACE)
57 fprintf (stderr ,"GC: new action %p '%s' cnt %ld parent '%s'\n",
58 self, name->str, name->refcnt >> 2, parent?parent->name->str:NULL);
60 return self;
63 MalaAction
64 mala_action_new_actioninit (MalaActionInit init, MalaEngine engine)
66 MalaStringBucket bucket = &engine->words;
67 MalaAction parent;
68 MalaAction self;
69 MalaString name;
70 void * data = NULL;
71 MalaDataFactory factory = init->factory;
73 name = mala_string_new (init->command, bucket);
74 if (!name)
75 return NULL;
77 if (factory)
79 data = factory ( &data, (char *)init->data, bucket);
80 if (!data)
81 goto ealloc;
83 else
84 data = init->data;
86 if (!init->parent)
87 parent = mala_action_get_cstr (bucket, "--WORLD");
88 else
89 parent = mala_action_get_cstr (bucket, init->parent);
91 self = mala_action_new (name, data, init->parser, factory, parent);
92 if (!self)
93 goto ealloc_action;
95 mala_string_free (name);
97 return self;
99 ealloc_action:
100 factory (&data, NULL, NULL);
101 ealloc:
102 mala_string_free (name);
103 return NULL;
106 MalaAction
107 mala_action_get_cstr (MalaStringBucket bucket, const char * name)
109 return name
110 ? mala_actiondesc_top (mala_string_user_get (mala_string_find (name, bucket)))
111 : NULL;
114 MalaAction
115 mala_action_get_str (MalaString name)
117 return name
118 ? mala_actiondesc_top (mala_string_user_get (name))
119 : NULL;
124 mala_action_attach (MalaAction self)
126 MalaActionDesc desc;
128 desc = mala_actiondesc_ensure (self->name);
129 if (!desc)
130 return MALA_EALLOC;
132 mala_actiondesc_push_action (desc, self);
133 return MALA_SUCCESS;
137 mala_action_execute (MalaAction self, MalaStringListNode_ref pptr, MalaEngine eng)
139 return self->parser ? self->parser (eng, pptr, self->data) : MALA_EPARSER;
145 void
146 mala_action_free (MalaAction self)
148 MalaAction child;
150 if (!self)
151 return;
153 MALA_ASSERT(self->name);
155 if (self->name->bucket && self->name->bucket->gc_trace > MALA_NOTRACE)
156 fprintf (stderr ,"GC: free action %p '%s'\n", self, self->name->str);
158 // detach from parent
159 if (self->parent)
161 self->parent = NULL;
162 LIST_REMOVE (self, cldnode);
165 // delete all childs
166 while ((child = self->childs.lh_first) != NULL)
168 LIST_REMOVE (child, cldnode);
169 mala_action_free (child);
172 if (self->factory && self->data)
174 self->factory (&self->data, NULL, NULL);
175 self->data = NULL;
178 LIST_REMOVE(self, stknode);
180 if (!self->desc->actions.lh_first)
181 mala_actiondesc_free (self->desc);
183 mala_string_free (self->name);
185 free (self);
192 #if 0 /*TODO*/
195 t_uchar *
196 mala_action_getname (MalaAction self)
198 return self->name;
202 mala_action_attach (MalaAction self, MalaAction parent)
204 if (!llist_is_empty (&self->cldnode))
205 return MALA_EACTIONUSED;
207 llist_add_tail (&parent->childs, &self->cldnode);
208 return MALA_SUCCESS;
211 void
212 mala_action_detach (MalaAction self)
214 llist_unlink (&self->cldnode);
217 MalaParserFunc
218 mala_action_getparser (MalaAction self)
220 return self->parser;
223 void *
224 mala_action_getdata (MalaAction self)
226 return self->data;
228 #endif /*TODO*/
232 // Local Variables:
233 // mode: C
234 // c-file-style: "gnu"
235 // End:
236 // arch-tag: 5b3b4c3c-09f4-4f2e-a737-1ea6c5df59e9
237 // end_of_file