BRL-CAD
observer.c
Go to the documentation of this file.
1 /* O B S E R V E R . C
2  * BRL-CAD
3  *
4  * Copyright (c) 1997-2014 United States Government as represented by
5  * the U.S. Army Research Laboratory.
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public License
9  * version 2.1 as published by the Free Software Foundation.
10  *
11  * This library is distributed in the hope that it will be useful, but
12  * WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this file; see the file named COPYING for more
18  * information.
19  */
20 
21 #include "common.h"
22 
23 #include <string.h>
24 
25 #include "bu/cmd.h"
26 #include "bu/malloc.h"
27 #include "bu/str.h"
28 #include "bu/bu_tcl.h"
29 
30 /**
31  * Attach observer.
32  *
33  * Usage:
34  * attach observer [cmd]
35  *
36  */
37 HIDDEN int
38 observer_attach(void *clientData, int argc, const char **argv)
39 {
40  struct bu_observer *headp = (struct bu_observer *)clientData;
41  struct bu_observer *op;
42 
43  if (argc < 2 || 3 < argc) {
44  bu_log("ERROR: expecting only three arguments\n");
45  return BRLCAD_ERROR;
46  }
47 
48  /* see if it already exists, if so, modify it */
49  for (BU_LIST_FOR(op, bu_observer, &headp->l))
50  if (BU_STR_EQUAL(bu_vls_addr(&op->observer), argv[1])) {
51  if (argc == 2)
52  /* clobber cmd */
53  bu_vls_init(&op->cmd);
54  else
55  /* overwrite cmd */
56  bu_vls_strcpy(&op->cmd, argv[2]);
57 
58  return BRLCAD_OK;
59  }
60 
61  /* acquire bu_observer struct */
62  BU_GET(op, struct bu_observer);
63 
64  /* initialize observer */
65  bu_vls_init(&op->observer);
66  bu_vls_strcpy(&op->observer, argv[1]);
67  bu_vls_init(&op->cmd);
68 
69  if (argc == 3)
70  bu_vls_strcpy(&op->cmd, argv[2]);
71 
72  /* append to list of bu_observer's */
73  BU_LIST_APPEND(&headp->l, &op->l);
74 
75  return BRLCAD_OK;
76 }
77 
78 
79 /**
80  * Detach observer.
81  *
82  * Usage:
83  * detach observer
84  *
85  */
86 HIDDEN int
87 observer_detach(void *clientData, int argc, const char **argv)
88 {
89  struct bu_observer *headp = (struct bu_observer *)clientData;
90  struct bu_observer *op;
91 
92  if (argc != 2) {
93  bu_log("ERROR: expecting two arguments\n");
94  return BRLCAD_ERROR;
95  }
96 
97  /* search for observer and remove from list */
98  for (BU_LIST_FOR(op, bu_observer, &headp->l))
99  if (BU_STR_EQUAL(bu_vls_addr(&op->observer), argv[1])) {
100  BU_LIST_DEQUEUE(&op->l);
101  bu_vls_free(&op->observer);
102  bu_vls_free(&op->cmd);
103  BU_PUT(op, struct bu_observer);
104 
105  return BRLCAD_OK;
106  }
107 
108  bu_log("detach: %s not found", argv[1]);
109  return BRLCAD_ERROR;
110 }
111 
112 
113 /**
114  * Show/list observers.
115  *
116  * Usage:
117  * show
118  *
119  */
120 HIDDEN int
121 observer_show(void *clientData, int argc, const char **UNUSED(argv))
122 {
123  struct bu_observer *headp = (struct bu_observer *)clientData;
124  struct bu_observer *op;
125 
126  if (argc != 1) {
127  bu_log("ERROR: expecting only one argument\n");
128  return BRLCAD_ERROR;
129  }
130 
131  for (BU_LIST_FOR(op, bu_observer, &headp->l)) {
132  bu_log("%s - %s\n", bu_vls_addr(&op->observer), bu_vls_addr(&op->cmd));
133  }
134 
135  return BRLCAD_OK;
136 }
137 
138 
139 void
140 bu_observer_notify(Tcl_Interp *interp, struct bu_observer *headp, char *self)
141 {
142  struct bu_observer *op;
143  struct bu_vls vls = BU_VLS_INIT_ZERO;
144 
145  for (BU_LIST_FOR(op, bu_observer, &headp->l)) {
146  if (bu_vls_strlen(&op->cmd) > 0) {
147  /* Execute cmd */
148  bu_vls_strcpy(&vls, bu_vls_addr(&op->cmd));
149  Tcl_Eval(interp, bu_vls_addr(&vls));
150  } else {
151  /* Assume that observer is some object that has an update method */
152  bu_vls_trunc(&vls, 0);
153  bu_vls_printf(&vls, "%s update %s", bu_vls_addr(&op->observer), self);
154  Tcl_Eval(interp, bu_vls_addr(&vls));
155  }
156  }
157  bu_vls_free(&vls);
158 }
159 
160 
161 void
163 {
164  struct bu_observer *op;
165  struct bu_observer *nop;
166 
167  op = BU_LIST_FIRST(bu_observer, &headp->l);
168  while (BU_LIST_NOT_HEAD(op, &headp->l)) {
169  nop = BU_LIST_PNEXT(bu_observer, op);
170  BU_LIST_DEQUEUE(&op->l);
171  bu_vls_free(&op->observer);
172  bu_vls_free(&op->cmd);
173  BU_PUT(op, struct bu_observer);
174  op = nop;
175  }
176 }
177 
178 
179 /**
180  * observer commands for libdm and librt's dg_obj, view_obj, and
181  * wdb_obj interfaces.
182  */
183 static struct bu_cmdtab bu_observer_cmds[] = {
184  {"attach", observer_attach},
185  {"detach", observer_detach},
186  {"show", observer_show},
187  {(const char *)NULL, BU_CMD_NULL}
188 };
189 
190 
191 int
192 bu_observer_cmd(void *clientData, int argc, const char **argv)
193 {
194  int ret;
195  if (bu_cmd(bu_observer_cmds, argc, argv, 0, clientData, &ret) == BRLCAD_OK)
196  return ret;
197 
198  bu_log("ERROR: '%s' command not found\n", argv[0]);
199  return BRLCAD_ERROR;
200 }
201 
202 
203 /*
204  * Local Variables:
205  * mode: C
206  * tab-width: 8
207  * indent-tabs-mode: t
208  * c-file-style: "stroustrup"
209  * End:
210  * ex: shiftwidth=4 tabstop=8
211  */
Definition: cmd.h:48
void bu_vls_init(struct bu_vls *vp)
Definition: vls.c:56
#define BU_LIST_FOR(p, structure, hp)
Definition: list.h:365
void bu_log(const char *,...) _BU_ATTR_PRINTF12
Definition: log.c:176
ustring interp
HIDDEN int observer_show(void *clientData, int argc, const char **argv)
Definition: observer.c:121
struct bu_vls observer
Definition: bu_tcl.h:49
void bu_vls_trunc(struct bu_vls *vp, int len)
Definition: vls.c:198
int bu_observer_cmd(void *clientData, int argc, const char **argv)
Definition: observer.c:192
Header file for the BRL-CAD common definitions.
#define BU_CMD_NULL
Definition: cmd.h:37
#define BU_LIST_APPEND(old, new)
Definition: list.h:197
struct bu_list l
Definition: bu_tcl.h:48
#define HIDDEN
Definition: common.h:86
void bu_vls_free(struct bu_vls *vp)
Definition: vls.c:248
HIDDEN int observer_detach(void *clientData, int argc, const char **argv)
Definition: observer.c:87
#define BRLCAD_OK
Definition: defines.h:71
#define BU_GET(_ptr, _type)
Definition: malloc.h:201
size_t bu_vls_strlen(const struct bu_vls *vp)
Definition: vls.c:189
#define BU_LIST_PNEXT(structure, p)
Definition: list.h:422
#define UNUSED(parameter)
Definition: common.h:239
#define BU_PUT(_ptr, _type)
Definition: malloc.h:215
char * bu_vls_addr(const struct bu_vls *vp)
Definition: vls.c:111
void bu_observer_free(struct bu_observer *headp)
Definition: observer.c:162
void bu_vls_printf(struct bu_vls *vls, const char *fmt,...) _BU_ATTR_PRINTF23
Definition: vls.c:694
void bu_vls_strcpy(struct bu_vls *vp, const char *s)
Definition: vls.c:310
HIDDEN int observer_attach(void *clientData, int argc, const char **argv)
Definition: observer.c:38
#define BU_VLS_INIT_ZERO
Definition: vls.h:84
#define BU_LIST_DEQUEUE(cur)
Definition: list.h:209
Definition: vls.h:56
#define BRLCAD_ERROR
Definition: defines.h:72
struct bu_vls cmd
Definition: bu_tcl.h:50
#define BU_LIST_NOT_HEAD(p, hp)
Definition: list.h:324
#define BU_LIST_FIRST(structure, hp)
Definition: list.h:312
int bu_cmd(const struct bu_cmdtab *cmds, int argc, const char *argv[], int cmd_index, void *data, int *result)
void bu_observer_notify(Tcl_Interp *interp, struct bu_observer *headp, char *self)
Definition: observer.c:140
#define BU_STR_EQUAL(s1, s2)
Definition: str.h:126