Example #1
0
void SaveEachClass(class_node *c)
{
	int i;
	
	if ((GetClassByID(c->class_id) != c) ||
		(c->super_id != NO_SUPERCLASS && GetClassByID(c->super_id) == NULL) ||
		(c->class_name == NULL))
	{
		eprintf("SaveEachClass is not saving invalid class %i\n",c->class_id);
		return;
	}
	
	SaveGameWriteByte(SAVE_GAME_CLASS);
	SaveGameWriteInt(c->class_id);
	SaveGameWriteString(c->class_name);
	SaveGameWriteInt(c->num_properties);
	
	for (i=1;i<=c->num_properties;i++)
	{
		const char *s = GetPropertyNameByID(c,i);
		if (!s)
		{
			eprintf("SaveEachClass cannot find property name for index %i in %s\n",i,c->fname);
			continue;
		}
		SaveGameWriteString(s);
	}
}
Example #2
0
void ResetObject()
{
   int i,old_objects;
   class_node *c;

   for (i=0;i<num_objects;i++)
   {
      if (!objects[i].deleted)
      {
	 c = GetClassByID(objects[i].class_id);
	 if (c == NULL)
	 {
	    eprintf("ResetObject can't find class id %i\n",objects[i].class_id);
	    return;
	 }

	 FreeMemory(MALLOC_ID_OBJECT_PROPERTIES,objects[i].p,
		    sizeof(prop_type)*(1+c->num_properties));
      }
   }
   old_objects = max_objects;
   num_objects = 0;  
   max_objects = INIT_OBJECTS;
   objects = (object_node *)
      ResizeMemory(MALLOC_ID_OBJECT,objects,old_objects*sizeof(object_node),
		   max_objects*sizeof(object_node));
}
Example #3
0
message_node *GetMessageByID(int class_id,int message_id,class_node **found_class)
{
   class_node *c;
   message_node *m;
   int i;

   c = GetClassByID(class_id);

   if (c == NULL)
   {
      eprintf("GetMessageByID can't find class %i\n",class_id);
      return NULL;
   }
   
   do
   {
      m = c->messages;

      for (i=0;i<c->num_messages;i++)
      {
	 if (m[i].message_id == message_id)
	 {
	    if (found_class != NULL)
	       *found_class = c;
	    return &m[i];
	 }
      }
      c = c->super_ptr;
   } while (c != NULL);

   return NULL;
}
Example #4
0
void SetClassNumMessages(int class_id,int num_messages)
{
   class_node *c;
   int i;

   c = GetClassByID(class_id);
   if (c == NULL)
   {
      eprintf("SetClassNumMessages can't find class %i\n",class_id);
      return;
   }

   if (num_messages == 0)
      return;

   c->messages = (message_node *)AllocateMemory(MALLOC_ID_MESSAGE,
						num_messages*sizeof(message_node));
   c->num_messages = num_messages;

   for (i=0;i<c->num_messages;i++)
   {
      c->messages[i].message_id = 0;
      c->messages[i].handler = 0;
      c->messages[i].dstr_id = INVALID_DSTR;
      c->messages[i].trace_session_id = INVALID_ID;
      c->messages[i].timed_call_count = 0;
      c->messages[i].untimed_call_count = 0;
      c->messages[i].total_call_time = 0.0;
      c->messages[i].propagate_message = NULL;
      c->messages[i].propagate_class = NULL;
   }  
}
Example #5
0
__inline void StoreValue(int object_id,local_var_type *local_vars,int data_type,int data,
						 val_type new_data)
{
	class_node *class_data;
	object_node *o;
	
	if (kod_stat.debugging)
	{
		if (new_data.v.tag == TAG_INVALID)
			eprintf("[%s] StoreValue trying to assign with uninitialized data (INVALID %i)\n",
			BlakodDebugInfo(),new_data.v.data);
	}
	
	switch (data_type)
	{
	case LOCAL_VAR : 
		if (data < 0 || data >= local_vars->num_locals)
		{
			eprintf("[%s] StoreValue can't write to illegal local var %i\n",
				BlakodDebugInfo(),data);
			return;
		}
		local_vars->locals[data].int_val = new_data.int_val;
		break;
		
	case PROPERTY : 
		o = GetObjectByID(object_id);
		if (o == NULL)
		{
			eprintf("[%s] StoreValue can't find object %i\n",
				BlakodDebugInfo(),object_id);
			return;
		}
		class_data = GetClassByID(o->class_id);
		if (class_data == NULL)
		{
			eprintf("[%s] StoreValue can't find class id %i\n",
				BlakodDebugInfo(),o->class_id);
			return;
		}
		/* equal to num_properties is ok, because self = prop 0 */
		if (data < 0 || data > class_data->num_properties) 
		{
			eprintf("[%s] StoreValue can't write to illegal property %i (max %i)\n",
				BlakodDebugInfo(),data,class_data->num_properties);
			return;
		}
		o->p[data].val.int_val = new_data.int_val; 
		break;
		
	default :
		eprintf("[%s] StoreValue can't identify type %i\n",
			BlakodDebugInfo(),data_type); 
		break;
	}
}
Example #6
0
void SendClassMessage(object_node *object)
{
	class_node *c = GetClassByID(object->class_id);
	do
	{
		if (c->class_id == classMsg.class_id)
		{
			SendBlakodMessage(object->object_id,classMsg.message_id,classMsg.num_params,classMsg.parm);
			numExecuted++;
			return;
		}
		c = c->super_ptr;
	} while (c != NULL);
}
Example #7
0
object_node * GetObjectByIDQuietly(int object_id)
{
   if (object_id < 0 || object_id >= num_objects)
   {
      return NULL;
   }
   if (objects[object_id].deleted)
   {
      class_node* c;
      c = GetClassByID(objects[object_id].class_id);
      return NULL;
   }

   return &objects[object_id];
}
Example #8
0
const char * GetDataName(val_type val)
{
   resource_node *r;
   class_node *c;
   static char s[10];
   val_type int_val;

   switch (val.v.tag)
   {
   case TAG_RESOURCE :
      r = GetResourceByID(val.v.data);
      if (r == NULL)
      {
         sprintf(s,"%i",val.v.data);
         return s;
      }
      if (r->resource_name == NULL)
      {
         sprintf(s,"%i",r->resource_id);
         return s;
      }
      return r->resource_name;

   case TAG_CLASS :
      c = GetClassByID(val.v.data);
      if (c == NULL)
      {
         eprintf("GetTagData error, can't find class id %i\n",val.v.data);
         sprintf(s,"%i",val.v.data);
         return s;
      }
      return c->class_name;

   case TAG_MESSAGE :
      // Message tag saving *is* supported, however is not advised as message ID
      // numbers can change and any resulting call could have undesired effects.
      eprintf("GetTagData error, message tag saving not supported %i\n",val.v.data);

      /* fall through */
   default :
      /* write as positive int so no problem reading in */
      int_val.v.tag = val.v.tag;
      int_val.v.data = val.v.data;
      sprintf(s,"%i",int_val.v.data);
      return s;
   }
}
Example #9
0
int AllocateObject(int class_id)
{
   int old_objects;
   class_node *c;

   c = GetClassByID(class_id);
   if (c == NULL)
   {
      eprintf("AllocateObject can't find class id %i\n",class_id);
      return INVALID_OBJECT;
   }

   if (num_objects == max_objects)
   {
      old_objects = max_objects;
      max_objects = max_objects * 2;
      objects = (object_node *)
	 ResizeMemory(MALLOC_ID_OBJECT,objects,old_objects*sizeof(object_node),
		      max_objects*sizeof(object_node));
      lprintf("AllocateObject resized to %i objects\n",max_objects);
   }

   objects[num_objects].object_id = num_objects;
   objects[num_objects].class_id = class_id;
   objects[num_objects].deleted = False;
   objects[num_objects].num_props = 1 + c->num_properties;
   objects[num_objects].p = (prop_type *)AllocateMemory(MALLOC_ID_OBJECT_PROPERTIES,
							sizeof(prop_type)*(1+c->num_properties));

   if (ConfigBool(DEBUG_INITPROPERTIES))
   {
      int i;
      prop_type p;

      p.id = 0;
      p.val.v.tag = TAG_INVALID;
      p.val.v.data = 0;

      for (i = 0; i < (1+c->num_properties); i++)
      {
	 objects[num_objects].p[i] = p;
      }
   }

   return num_objects++;
}
Example #10
0
Bool SetObjectPropertyByName(int object_id,char *prop_name,val_type val)
{
   object_node *o;
   class_node *c;
   int property_id;
   
   o = GetObjectByID(object_id);
   if (o == NULL)
   {
      eprintf("SetObjectPropertyByName can't find object %i\n",object_id);
      return False;
   }

   c = GetClassByID(o->class_id);
   if (c == NULL) 
   {
      eprintf("SetObjectPropertyByName can't find class %i\n",
	      o->class_id);
      return False;
   }

   property_id = GetPropertyIDByName(c,prop_name);
   if (property_id == INVALID_PROPERTY)
   {
      eprintf("SetObjectPropertyByName can't find property %s in class %s (%i)\n",
	      prop_name, c->class_name, c->class_id);
      return False;
   }

   if (o->num_props <= property_id)
   {
      eprintf("SetObjectPropertyByName property index/id %i not in object %i class %s (%i)\n",
	      property_id,object_id,c->class_name,c->class_id);
      return False;
   }
   
   if (o->p[property_id].id != property_id)
   {
      eprintf("SetObjectPropertyByName property index/id mismatch %i %i\n",
	      property_id,o->p[property_id].id);
      return False;
   }

   o->p[property_id].val = val;
   return True;
}
Example #11
0
object_node * GetObjectByID(int object_id)
{
   if (object_id < 0 || object_id >= num_objects)
   {
      eprintf("GetObjectByID can't retrieve invalid object %i\n",object_id);
      return NULL;
   }
   if (objects[object_id].deleted)
   {
      class_node* c;
      c = GetClassByID(objects[object_id].class_id);
      if (c)
	 eprintf("GetObjectByID can't retrieve deleted OBJECT %i which was CLASS %s\n",object_id,c->class_name);
      else
	 eprintf("GetObjectByID can't retrieve deleted OBJECT %i, unknown or invalid class\n",object_id);
      return NULL;
   }
   return &objects[object_id];
}
Example #12
0
int CreateObject(int class_id,int num_parms,parm_node parms[])
{
   int new_object_id;
   class_node *c;

   new_object_id = AllocateObject(class_id);

   if (new_object_id == INVALID_OBJECT)
      return INVALID_OBJECT;
   
   /* set self = prop 0 */
   objects[new_object_id].p[0].id = 0; 
   objects[new_object_id].p[0].val.v.tag = TAG_OBJECT; 
   objects[new_object_id].p[0].val.v.data = new_object_id;

   c = GetClassByID(class_id);
   if (c == NULL) /* can't ever be, because AllocateObject checks */
   {
      eprintf("CreateObject can't find class id %i\n",class_id);
      return INVALID_OBJECT;
   }

   SetObjectProperties(new_object_id,c);

   /* might not be top level message, since can be called from blakod.  If it
      really IS a top level message, then it better not post anything, since
      post messages won't be handled */
   if (IsInterpreting())
      SendBlakodMessage(new_object_id,CONSTRUCTOR_MSG,num_parms,parms);
   else
      SendTopLevelBlakodMessage(new_object_id,CONSTRUCTOR_MSG,num_parms,parms);

   if (ConfigBool(DEBUG_UNINITIALIZED))
   {
      int i;
      for (i = 0; i < (1+c->num_properties); i++)
	 if (objects[new_object_id].p[i].val.v.tag == TAG_INVALID)
	    eprintf("Uninitialized properties after constructor, class %s\n",
	       c->class_name);
   }

   return new_object_id;
}
Example #13
0
char *BlakodDebugInfo()
{
	static char s[100];
	class_node *c;

	if (kod_stat.interpreting_class == INVALID_CLASS)
	{
		sprintf(s,"Server");
	}
	else
	{
		c = GetClassByID(kod_stat.interpreting_class);
		if (c == NULL)
			sprintf(s,"Invalid class %i",kod_stat.interpreting_class);
		else
			sprintf(s,"%s (%i)",c->fname,GetSourceLine(c,bkod));
	}
	return s;
}
Example #14
0
void AddMessage(int class_id,int count,int message_id,char *offset,int dstr_id)
{
   class_node *c;

   /* count which message in the table we are setting */

   c = GetClassByID(class_id);
   if (c == NULL)
   {
      eprintf("AddMessage can't find class %i\n",class_id);
      return;
   }

   c->messages[count].message_id = message_id;
   c->messages[count].handler = offset;
   c->messages[count].dstr_id = dstr_id;
   c->messages[count].trace_session_id = INVALID_ID;
   c->messages[count].called_count = 0;
}
Example #15
0
void SaveEachObject(object_node *o)
{
	int i;
	class_node *c;
	
	c = GetClassByID(o->class_id);
	if (c == NULL)
	{
		eprintf("SaveEachObject can't get class %i\n",o->class_id);
		return;
	}
	
	SaveGameWriteByte(SAVE_GAME_OBJECT);
	SaveGameWriteInt(o->object_id);
	SaveGameWriteInt(o->class_id);
	SaveGameWriteInt(c->num_properties);
	
	/* remember, don't save self (p[0]) because no name for it!
    * loadall will set self for us, fortunately.
    */
	/* equal to num_properties is ok, because self = prop 0 */
	for (i=1;i<=c->num_properties;i++)
		SaveGameWriteInt(o->p[i].val.int_val);
}
Example #16
0
void DeleteBlakodObject(int object_id)
{
   class_node *c;
   object_node *o;

   o = GetObjectByID(object_id);
   if (o == NULL)
   {
      eprintf("DeleteBlakodObject can't get an object by ID %i!\n",object_id);
      return;
   }

   c = GetClassByID(o->class_id);
   if (c == NULL)
   {
      eprintf("DeleteBlakodObject can't find class %i\n",o->class_id);
      return;
   }

   /* now remove object */

   FreeMemory(MALLOC_ID_OBJECT_PROPERTIES,o->p,sizeof(prop_type)*(1+c->num_properties));
   o->deleted = True;
}   
Example #17
0
/* returns the return value of the blakod */
int SendBlakodMessage(int object_id,int message_id,int num_parms,parm_node parms[])
{
	object_node *o;
	class_node *c,*propagate_class;
	message_node *m;
	val_type message_ret;
	
	int prev_interpreting_class;
	char *prev_bkod;

	int propagate_depth = 0;

	prev_bkod = bkod;
	prev_interpreting_class = kod_stat.interpreting_class;
	
	o = GetObjectByID(object_id);
	if (o == NULL)
	{
		bprintf("SendBlakodMessage can't find OBJECT %i\n",object_id);
		return NIL;
	}
	
	c = GetClassByID(o->class_id);
	if (c == NULL)
	{
		eprintf("SendBlakodMessage OBJECT %i can't find CLASS %i\n",
			object_id,o->class_id);
		return NIL;
	}
	
	m = GetMessageByID(c->class_id,message_id,&c);
	
	if (m == NULL)
	{
		bprintf("SendBlakodMessage CLASS %s (%i) OBJECT %i can't find a handler for MESSAGE %s (%i)\n",
			c->class_name,c->class_id,object_id,GetNameByID(message_id),message_id);
		return NIL;
	}
	
	m->called_count++;
	
	kod_stat.num_messages++;
	stack[message_depth].class_id = c->class_id;
	stack[message_depth].message_id = m->message_id;
	stack[message_depth].propagate_depth = 0;
	stack[message_depth].num_parms = num_parms;
	memcpy(stack[message_depth].parms,parms,num_parms*sizeof(parm_node));
	stack[message_depth].bkod_ptr = bkod;
	if (message_depth > 0)
		stack[message_depth-1].bkod_ptr = prev_bkod;
	message_depth++;
	if (message_depth > kod_stat.message_depth_highest)
		kod_stat.message_depth_highest = message_depth;
	
	if (message_depth >= MAX_DEPTH)
	{
		bprintf("SendBlakodMessage sending to CLASS %s (%i), depth is %i, aborted!\n",
			c->class_name,c->class_id,message_depth);
		
		kod_stat.interpreting_class = prev_interpreting_class;
		message_depth--;
		bkod = prev_bkod;
		
		return NIL;
	}
	
	if (m->trace_session_id != INVALID_ID)
	{
		trace_session_id = m->trace_session_id;
		m->trace_session_id = INVALID_ID;
	}
	
	if (trace_session_id != INVALID_ID)
		TraceInfo(trace_session_id,c->class_name,m->message_id,num_parms,parms);
	
	kod_stat.interpreting_class = c->class_id;
	
	bkod = m->handler;
	
	propagate_depth = 1;

	while (InterpretAtMessage(object_id,c,m,num_parms,parms,&message_ret) 
		== RETURN_PROPAGATE)
	{
		propagate_class = m->propagate_class;
		m = m->propagate_message;
		
		if (m == NULL)
		{
			bprintf("SendBlakodMessage can't propagate MESSAGE %s (%i) in CLASS %s (%i)\n",
				GetNameByID(message_id),message_id,c->class_name,c->class_id);
			message_depth -= propagate_depth;
			kod_stat.interpreting_class = prev_interpreting_class;
			bkod = prev_bkod;
			return NIL;
		}
		
		if (propagate_class == NULL)
		{
			bprintf("SendBlakodMessage can't find class to propagate to, from "
				"MESSAGE %s (%i) in CLASS %s (%i)\n",GetNameByID(message_id),message_id,c->class_name,c->class_id);
			message_depth -= propagate_depth;
			kod_stat.interpreting_class = prev_interpreting_class;
			bkod = prev_bkod;
			return NIL;
		}
		
		c = propagate_class;
		
		m->called_count++;
		
		if (m->trace_session_id != INVALID_ID)
		{
			trace_session_id = m->trace_session_id;
			m->trace_session_id = INVALID_ID;
		}
		
		if (trace_session_id != INVALID_ID)
			TraceInfo(trace_session_id,"(propagate)",m->message_id,num_parms,parms);
		
		kod_stat.interpreting_class = c->class_id;
		
		stack[message_depth-1].bkod_ptr = bkod;

		stack[message_depth].class_id = c->class_id;
		stack[message_depth].message_id = m->message_id;
		stack[message_depth].propagate_depth = propagate_depth;
		stack[message_depth].num_parms = num_parms;
		memcpy(stack[message_depth].parms,parms,num_parms*sizeof(parm_node));
		stack[message_depth].bkod_ptr = m->handler;
		message_depth++;
		propagate_depth++;

		bkod = m->handler;

	}
	
	message_depth -= propagate_depth;
	kod_stat.interpreting_class = prev_interpreting_class;
	bkod = prev_bkod;
	
	return message_ret.int_val;
}
Example #18
0
/* returns the return value of the blakod */
int SendTopLevelBlakodMessage(int object_id,int message_id,int num_parms,parm_node parms[])
{
	int ret_val = 0;
	UINT64 start_time = 0;
	int interp_time = 0;
	int posts = 0;
	int accumulated_num_interpreted = 0;
	
	if (message_depth != 0)
	{
		eprintf("SendTopLevelBlakodMessage called with message_depth %i\n",message_depth);
	}
	
	kod_stat.debugging = ConfigBool(DEBUG_UNINITIALIZED);
	
	start_time = GetMilliCount();
	kod_stat.num_top_level_messages++;
	trace_session_id = INVALID_ID;
	num_interpreted = 0;
	
	ret_val = SendBlakodMessage(object_id,message_id,num_parms,parms);
	
	while (post_q.next != post_q.last)
	{
		posts++;
		
		accumulated_num_interpreted += num_interpreted;
		num_interpreted = 0;
		
		if (accumulated_num_interpreted > 10*ConfigInt(BLAKOD_MAX_STATEMENTS))
		{
			bprintf("SendTopLevelBlakodMessage too many instructions in posted followups\n");
			
			dprintf("SendTopLevelBlakodMessage too many instructions in posted followups\n");
			dprintf("  OBJECT %i CLASS %s MESSAGE %s (%i) some followups are being aborted\n",
				object_id,
				GetClassByID(GetObjectByID(object_id)->class_id)->class_name,
				GetNameByID(message_id), message_id);
			
			break;
		}
		
		/* posted messages' return value is ignored */
		SendBlakodMessage(post_q.data[post_q.last].object_id,post_q.data[post_q.last].message_id,
			post_q.data[post_q.last].num_parms,post_q.data[post_q.last].parms);
		
		post_q.last = (post_q.last + 1) % MAX_POST_QUEUE;
	}
	
	interp_time = (int)(GetMilliCount() - start_time);
	kod_stat.interpreting_time += interp_time;
	if (interp_time > kod_stat.interpreting_time_highest)
	{
		kod_stat.interpreting_time_highest = interp_time;
		kod_stat.interpreting_time_message_id = message_id;
		kod_stat.interpreting_time_object_id = object_id;
		kod_stat.interpreting_time_posts = posts;
	}
	if (interp_time > 1000)
	{
		kod_stat.interpreting_time_over_second++;
		kod_stat.interpreting_time_message_id = message_id;
		kod_stat.interpreting_time_object_id = object_id;
		kod_stat.interpreting_time_posts = posts;
	}
	
	if (num_interpreted > kod_stat.num_interpreted_highest)
		kod_stat.num_interpreted_highest = num_interpreted;
	
	kod_stat.num_interpreted += num_interpreted;
	if (kod_stat.num_interpreted > 1000000000L)
	{
		kod_stat.num_interpreted -= 1000000000L;
		kod_stat.billions_interpreted++;
	}
	
	if (message_depth != 0)
	{
		eprintf("SendTopLevelBlakodMessage returning with message_depth %i\n",message_depth);
	}
	
	return ret_val;
}
Example #19
0
char *BlakodStackInfo()
{
	static char buf[5000];
	class_node *c;
	int i;

	buf[0] = '\0';
	for (i=message_depth-1;i>=0;i--)
	{
		char s[1000];
		if (stack[i].class_id == INVALID_CLASS)
		{
			sprintf(s,"Server");
		}
		else
		{
			c = GetClassByID(stack[i].class_id);
			if (c == NULL)
				sprintf(s,"Invalid class %i",stack[i].class_id);
			else
			{
				char *bp;
				char *class_name;
				char buf2[200];
				char parms[800];
				int j;

				/* for current frame, stack[] has pointer at beginning of function;
					use current pointer instead */
				bp = stack[i].bkod_ptr;
				if (i == message_depth-1)
					bp = bkod;

				class_name = "(unknown)";
				if (c->class_name)
					class_name = c->class_name;
				/* use %.*s with a fixed string of pluses to get exactly one plus per
					propagate depth */
				sprintf(s,"%.*s%s::%s",stack[i].propagate_depth,"++++++++++++++++++++++",class_name,GetNameByID(stack[i].message_id));
				strcat(s,"(");
				parms[0] = '\0';
				for (j=0;j<stack[i].num_parms;j++)
				{
					val_type val;
					val.int_val = stack[i].parms[j].value;
					sprintf(buf2,"#%s=%s %s",GetNameByID(stack[i].parms[j].name_id),
							  GetTagName(val),GetDataName(val));
					if (j > 0)
						strcat(parms,",");
					strcat(parms,buf2);
				}
				strcat(s,parms);
				strcat(s,")");
				sprintf(buf2," %s (%i)",c->fname,GetSourceLine(c,bp));
				strcat(s,buf2);
			}
		}
		if (i < message_depth-1)
			strcat(buf,"\n");
		strcat(buf,s);
		if (strlen(buf) > sizeof(buf) - 1000)
		{
			strcat(buf,"\n...and more");
			break;
		}
	}
	return buf;
}