#ifndef COMPONENT_H #define COMPONENT_H /* $Id: component.h,v 10.1 92/10/06 23:08:09 ca Exp $ */ /********************************************** The component structure. Describes the structure used to store the hosts, switches, links, etc. This is a generic structure used to refer to a component when the differences don't matter. The individual components (link, host, etc.) will have different data in the tail end of the component structure, (and may be different sizes), but the beginning is all the same. The list of components will be a doubly-linked list. The links are used only for operations that need to access all the components (saving, broadcast events, etc). */ #include "sim.h" #include "q.h" #include "list.h" #include "simx1.h" /* for GRAF_OBJECT & COMP_OBJECT */ char *make_int_text(), *make_bool_text(), *pktq_text(), *make_short_int_text(); char *make_double_text(), *make_short_double_text(); char *make_str_text(), *make_short_str_text(); char *make_short_bool_text(), *pktq_short_text(); char *make_char_text(), *make_short_char_text(); char *make_text(), *make_name_text(), *make_short_name_text(); char *q_text(), *q_short_text(); double bool_calc(), pktq_calc(), int_calc(), double_calc(), color_calc(); double q_calc(); int param_input_int(), param_input_double(), param_input_char(), param_input_str(), param_input_bool(), param_input_name(); /* Structure to store parameters */ typedef struct _Param { struct _Param *p_next; /* So these can be put in a queue */ char p_name[40]; /* Name of this param for display */ PFD p_calc_val; /* Routine that computes a value to be displayed in a meter. Used only for parameters that can be metered. Syntax: double val = (*calc_val)(c, p) Component *c; This component PARAM *p; This parameter */ PFP p_make_text; /* Routine to make a string containing some representation of the current value of this parameter. Needed for all params that are displayed in an infowindow. Syntax: char *text = (*make_text)(c, p) Component *c; PARAM *p; */ PFP p_make_short_text; /* As p_make_text, but only the value. eg, instead of "Processing delay: 1000", just "1000". Present in all parameters. (Used to save the world in a file.) */ PFI p_input; /* Routine to input this parameter. Passed a string and the parameter--returns TRUE if the string is a legal value, FALSE otherwise. p_make_short_text and p_input are converses. ie, p_input(p, p_make_short_text(c, p)) ==> no change to parameter. Syntax: (*p_input)(p, string, c) Param *p; char *string; Component *c; */ GRAF_OBJECT p_my_picture; /* The graphics object that displays this */ int p_display_type; /* Type of meter or whatever to display */ int p_flags; /* Flags about how to display this, including: Whether this is now displayed or not. If it has been changed since last screen update. */ int p_log; /* Integer associated with this param for log*/ double p_scale; /* Scale to use for meters */ union p_data { /* Union to store whatever data in. */ int i; /* The graphics library should not muck */ double d; /* with this-- it is used & maintained by */ caddr_t p; /* the simulator. */ struct { caddr_t p; int i; } pi; /* ... etc. ... */ } u; } Param; typedef struct _Component { struct _Component *co_next, *co_prev; /* Links to other components in the list */ short co_class; /* Class of component */ short co_type; /* Type of component that I am. */ char co_name[40]; /* Name of component (appears on screen) */ PFP co_action; /* Main function of component. Is called with each event that happens. Syntax: Many arguments needed. */ COMP_OBJECT co_picture; /* Graphics object that displays this thing */ /* Doubly linked list of neighbors. Data stored for each neighbor includes a PARAM structure, and possibly some other stuff. The graphics routines will have to follow this list if they are going to display any data associated with individual neighbors. */ list *co_neighbors; /* Parameters-- data that will be displayed on screen */ /* The number of parameters is fixed for each type of component. */ short co_menu_up; /* If true, then the text window is up */ queue *co_params; /* Variable-length queue of parameters */ /* Any other info that component needs to keep-- will vary. . . . */ } Component; /* Macro to reference parameters */ #include "log.h" /* For log_param() */ #define pval(comp, name) ( comp->name ) #define pupdatei(comp, name, expr) { \ pval(comp, name)->u.i = expr; \ log_param((Component *)(comp), pval(comp, name)); \ } #define pupdated(comp, name, expr) { \ pval(comp, name)->u.d = expr; \ log_param((Component *)(comp), pval(comp, name)); \ } /* co_neighbors is list of these structures */ typedef struct _Neighbor { struct _Neighbor *n_next, *n_prev; /* Links for the list. */ Component *n_c; /* Pointer to the neighboring component */ /* The next values will vary from network to network, and from component to component. For example, only switches & hosts have queues in the current application. */ queue *n_pq; /* Queue of packets to be sent */ short n_busy; /* True if the neighbor is busy */ double n_prev_sample; /* Previous sample time used for utilization calculation in links */ Param *n_p; /* index of parameter to display whatever */ Param *n_pp; /* index of parameter to display whatever */ caddr_t n_data; /* If a component wants to store arbitrary data for each neighbor, put it here. */ } Neighbor; Neighbor *find_neighbor(); Neighbor *add_neighbor(register Component *c, register Component *neighc, int max_num_neighbors, int num_classes, ... ); Param *param_init(); #endif /* COMPONENT_H */