/* * t4event.cpp -- * * Implementation of the T4Graph command to manage user defined events. * * Authors: Jacob Levy and Jean-Claude Wippler. * jyl@best.com jcw@equi4.com * * Copyright (c) 2000-2003, JYL Software Inc. * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE, EVEN IF * JYL SOFTWARE INC. IS MADE AWARE OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "genobject.h" #include "t4graphrep.h" /* * T4Graph_EventProc -- * * This procedure is called when "tgraph::event" is invoked. * Syntax: * tgraph::event define * tgraph::event isdefined * tgraph::event undefine * * The first form defines a new event token and returns it. * The second form checks whether an event token is defined. * The third form undefines an event token previously returned * from "tgraph::event define". * * Results: * A standard Tcl result. The interpreter result will contain a * value appropriate for the subcommand invoked. * * Side effects: * Depends on the subcommand invoked. */ static CONST84 char *subCommands[] = { (char *) "define", (char *) "isdefined", (char *) "undefine", (char *) "cause", (char *) NULL }; typedef enum ESubCommands { EDefine = 0, EIsDefined, EUndefine, ECause } ESubCommands; int T4Graph_EventProc(ClientData cd, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { ESubCommands index; T4InternalRep *intrep; T4Kinds kind; e4_Storage s; e4_Node n; e4_Vertex v; int eventcode; /* * There must be at least two arguments. */ if (objc < 2) { Tcl_WrongNumArgs(interp, 0, NULL, "tgraph::event cmd ?arg ...?"); return TCL_ERROR; } /* * Identify the operation requested. */ if (Tcl_GetIndexFromObj(interp, objv[1], (CONST84 char **) subCommands, (char *) "cmd", 0, (int *) &index) != TCL_OK) { return TCL_ERROR; } /* * Do the subcommand: */ switch (index) { case EDefine: /* * Define a new event code: */ if (objc != 2) { Tcl_WrongNumArgs(interp, 0, NULL, "tgraph::event define"); return TCL_ERROR; } if (!e4_Storage::DefineEventCode(eventcode)) { Tcl_AppendResult(interp, "cannot define new event", NULL); return TCL_ERROR; } Tcl_SetIntObj(Tcl_GetObjResult(interp), eventcode); return TCL_OK; case EIsDefined: /* * Check whether a given event code is defined: */ if (objc != 3) { Tcl_WrongNumArgs(interp, 0, NULL, "tgraph::event isdefined eventtoken"); return TCL_ERROR; } if (Tcl_GetIntFromObj(interp, objv[2], &eventcode) == TCL_ERROR) { return TCL_ERROR; } Tcl_SetBooleanObj(Tcl_GetObjResult(interp), e4_Storage::IsEventCodeDefined(eventcode) ? 1 : 0); return TCL_OK; case EUndefine: /* * Undefine an existing event code: */ if (objc != 3) { Tcl_WrongNumArgs(interp, 0, NULL, "tgraph::event undefine eventcode"); return TCL_ERROR; } if (Tcl_GetIntFromObj(interp, objv[2], &eventcode) == TCL_ERROR) { return TCL_ERROR; } Tcl_SetBooleanObj(Tcl_GetObjResult(interp), e4_Storage::UndefineEventCode(eventcode) ? 1 : 0); return TCL_OK; case ECause: /* * Cause an event on a storage entity: */ if ((objc != 4) && (objc != 5)) { Tcl_WrongNumArgs(interp, 0, NULL, "tgraph::event cause eventcode ent ?userdata?"); return TCL_ERROR; } if (Tcl_GetIntFromObj(interp, objv[2], &eventcode) == TCL_ERROR) { return TCL_ERROR; } intrep = (T4InternalRep *) GO_GetUncheckedInternalRep(objv[3]); if (intrep == NULL) { Tcl_AppendResult(interp, "incorrect third argument: must be storage, node", ", or vertex", NULL); return TCL_ERROR; } kind = intrep->KindIdentifier(); switch (kind) { case T4GRAPH_ILLEGAL: Tcl_AppendResult(interp, "incorrect third argument: must be storage, node", ", or vertex", NULL); return TCL_ERROR; case T4GRAPH_STORAGE: ((T4Storage *) intrep)->ExternalizeStorage(s); if (s.CauseEvent(eventcode, s, (objc == 5) ? objv[4] : NULL)) { return TCL_OK; } Tcl_AppendResult(interp, "cannot cause event ", Tcl_GetString(objv[2]), " on ", Tcl_GetString(objv[3]), NULL); return TCL_ERROR; case T4GRAPH_NODE: ((T4Node *) intrep)->ExternalizeNode(n); if (!n.GetStorage(s)) { Tcl_AppendResult(interp, "cannot cause event ", Tcl_GetString(objv[2]), " on ", Tcl_GetString(objv[3]), NULL); return TCL_ERROR; } if (s.CauseEvent(eventcode, n, (objc == 5) ? objv[4] : NULL)) { return TCL_OK; } Tcl_AppendResult(interp, "cannot cause event ", Tcl_GetString(objv[2]), " on ", Tcl_GetString(objv[3]), NULL); return TCL_ERROR; case T4GRAPH_VERTEX: ((T4Vertex *) intrep)->ExternalizeVertex(v); if (!v.GetStorage(s)) { Tcl_AppendResult(interp, "cannot cause event ", Tcl_GetString(objv[2]), " on ", Tcl_GetString(objv[3]), NULL); return TCL_ERROR; } if (s.CauseEvent(eventcode, v, (objc == 5) ? objv[4] : NULL)) { return TCL_OK; } Tcl_AppendResult(interp, "cannot cause event ", Tcl_GetString(objv[2]), " on ", Tcl_GetString(objv[3]), NULL); return TCL_ERROR; } } Tcl_AppendResult(interp, "unreachable code! in tgraph::event handler", NULL); return TCL_ERROR; }