⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 utility.c

📁 VC嵌入式CLips专家系统,实现战场环境的目标识别
💻 C
📖 第 1 页 / 共 2 页
字号:
   /*******************************************************/
   /*      "C" Language Integrated Production System      */
   /*                                                     */
   /*             CLIPS Version 6.24  06/05/06            */
   /*                                                     */
   /*                   UTILITY MODULE                    */
   /*******************************************************/

/*************************************************************/
/* Purpose: Provides a set of utility functions useful to    */
/*   other modules. Primarily these are the functions for    */
/*   handling periodic garbage collection and appending      */
/*   string data.                                            */
/*                                                           */
/* Principal Programmer(s):                                  */
/*      Gary D. Riley                                        */
/*                                                           */
/* Contributing Programmer(s):                               */
/*      Brian Donnell                                        */
/*                                                           */
/* Revision History:                                         */
/*                                                           */
/*      6.24: Renamed BOOLEAN macro type to intBool.         */
/*                                                           */
/*************************************************************/

#define _UTILITY_SOURCE_

#include "setup.h"

#include <ctype.h>
#include <stdlib.h>

#include <stdio.h>
#define _STDIO_INCLUDED_
#include <string.h>

#include "envrnmnt.h"
#include "evaluatn.h"
#include "facthsh.h"
#include "memalloc.h"
#include "multifld.h"
#include "prntutil.h"

#include "utility.h"

#define MAX_EPHEMERAL_COUNT 1000L
#define MAX_EPHEMERAL_SIZE 10240L
#define COUNT_INCREMENT 1000L
#define SIZE_INCREMENT 10240L

/***************************************/
/* LOCAL INTERNAL FUNCTION DEFINITIONS */
/***************************************/

   static intBool                 AddCPFunction(void *,char *,void (*)(void *),
                                                int,struct cleanupFunction **,intBool);
   static intBool                 RemoveCPFunction(void *,char *,struct cleanupFunction **);
   static void                    DeallocateUtilityData(void *);

/************************************************/
/* InitializeUtilityData: Allocates environment */
/*    data for utility routines.                */
/************************************************/
globle void InitializeUtilityData(
  void *theEnv)
  {
   AllocateEnvironmentData(theEnv,UTILITY_DATA,sizeof(struct utilityData),DeallocateUtilityData);
   
   UtilityData(theEnv)->GarbageCollectionLocks = 0;
   UtilityData(theEnv)->GarbageCollectionHeuristicsEnabled = TRUE;
   UtilityData(theEnv)->PeriodicFunctionsEnabled = TRUE;
   UtilityData(theEnv)->YieldFunctionEnabled = TRUE;

   UtilityData(theEnv)->CurrentEphemeralCountMax = MAX_EPHEMERAL_COUNT;
   UtilityData(theEnv)->CurrentEphemeralSizeMax = MAX_EPHEMERAL_SIZE;
   UtilityData(theEnv)->LastEvaluationDepth = -1;
  }
  
/**************************************************/
/* DeallocateUtilityData: Deallocates environment */
/*    data for utility routines.                  */
/**************************************************/
static void DeallocateUtilityData(
  void *theEnv)
  {
   struct cleanupFunction *tmpPtr, *nextPtr;

   tmpPtr = UtilityData(theEnv)->ListOfPeriodicFunctions;
   while (tmpPtr != NULL)
     {
      nextPtr = tmpPtr->next;
      rtn_struct(theEnv,cleanupFunction,tmpPtr);
      tmpPtr = nextPtr;
     }

   tmpPtr = UtilityData(theEnv)->ListOfCleanupFunctions;
   while (tmpPtr != NULL)
     {
      nextPtr = tmpPtr->next;
      rtn_struct(theEnv,cleanupFunction,tmpPtr);
      tmpPtr = nextPtr;
     }
  }

/*************************************************************/
/* PeriodicCleanup: Returns garbage created during execution */
/*   that has not been returned to the memory pool yet. The  */
/*   cleanup is normally deferred so that an executing rule  */
/*   can still access these data structures. Always calls a  */
/*   series of functions that should be called periodically. */
/*   Usually used by interfaces to update displays.          */
/*************************************************************/
globle void PeriodicCleanup(
  void *theEnv,
  intBool cleanupAllDepths,
  intBool useHeuristics)
  {
   int oldDepth = -1;
   struct cleanupFunction *cleanupPtr,*periodPtr;

   /*===================================*/
   /* Don't use heuristics if disabled. */
   /*===================================*/
   
   if (! UtilityData(theEnv)->GarbageCollectionHeuristicsEnabled) 
     { useHeuristics = FALSE; }
     
   /*=============================================*/
   /* Call functions for handling periodic tasks. */
   /*=============================================*/

   if (UtilityData(theEnv)->PeriodicFunctionsEnabled)
     {
      for (periodPtr = UtilityData(theEnv)->ListOfPeriodicFunctions;
           periodPtr != NULL;
           periodPtr = periodPtr->next)
        { 
         if (periodPtr->environmentAware)
           { (*periodPtr->ip)(theEnv); }
         else            
           { (* (void (*)(void)) periodPtr->ip)(); }
        }
     }
     
   /*===================================================*/
   /* If the last level we performed cleanup was deeper */
   /* than the current level, reset the values used by  */
   /* the heuristics to determine if garbage collection */
   /* should be performed. If the heuristic values had  */
   /* to be incremented because there was no garbage    */
   /* that could be cleaned up, we don't want to keep   */
   /* those same high values permanently so we reset    */
   /* them when we go back to a lower evaluation depth. */
   /*===================================================*/

   if (UtilityData(theEnv)->LastEvaluationDepth > EvaluationData(theEnv)->CurrentEvaluationDepth)
     {
      UtilityData(theEnv)->LastEvaluationDepth = EvaluationData(theEnv)->CurrentEvaluationDepth;
      UtilityData(theEnv)->CurrentEphemeralCountMax = MAX_EPHEMERAL_COUNT;
      UtilityData(theEnv)->CurrentEphemeralSizeMax = MAX_EPHEMERAL_SIZE;
     }

   /*======================================================*/
   /* If we're using heuristics to determine if garbage    */
   /* collection to occur, then check to see if enough     */
   /* garbage has been created to make cleanup worthwhile. */
   /*======================================================*/

   if (UtilityData(theEnv)->GarbageCollectionLocks > 0)  return;
   
   if (useHeuristics &&
       (UtilityData(theEnv)->EphemeralItemCount < UtilityData(theEnv)->CurrentEphemeralCountMax) &&
       (UtilityData(theEnv)->EphemeralItemSize < UtilityData(theEnv)->CurrentEphemeralSizeMax))
     { return; }

   /*==========================================================*/
   /* If cleanup is being performed at all depths, rather than */
   /* just the current evaluation depth, then temporarily set  */
   /* the evaluation depth to a level that will force cleanup  */
   /* at all depths.                                           */
   /*==========================================================*/

   if (cleanupAllDepths)
     {
      oldDepth = EvaluationData(theEnv)->CurrentEvaluationDepth;
      EvaluationData(theEnv)->CurrentEvaluationDepth = -1;
     }

   /*=============================================*/
   /* Free up multifield values no longer in use. */
   /*=============================================*/

   FlushMultifields(theEnv);

   /*=====================================*/
   /* Call the list of cleanup functions. */
   /*=====================================*/

   for (cleanupPtr = UtilityData(theEnv)->ListOfCleanupFunctions;
        cleanupPtr != NULL;
        cleanupPtr = cleanupPtr->next)
     {
      if (cleanupPtr->environmentAware)
        { (*cleanupPtr->ip)(theEnv); }
      else            
        { (* (void (*)(void)) cleanupPtr->ip)(); }
    }

   /*================================================*/
   /* Free up atomic values that are no longer used. */
   /*================================================*/

   RemoveEphemeralAtoms(theEnv);

   /*=========================================*/
   /* Restore the evaluation depth if cleanup */
   /* was performed on all depths.            */
   /*=========================================*/

   if (cleanupAllDepths) EvaluationData(theEnv)->CurrentEvaluationDepth = oldDepth;

   /*============================================================*/
   /* If very little memory was freed up, then increment the     */
   /* values used by the heuristics so that we don't continually */
   /* try to free up memory that isn't being released.           */
   /*============================================================*/

   if ((UtilityData(theEnv)->EphemeralItemCount + COUNT_INCREMENT) > UtilityData(theEnv)->CurrentEphemeralCountMax)
     { UtilityData(theEnv)->CurrentEphemeralCountMax = UtilityData(theEnv)->EphemeralItemCount + COUNT_INCREMENT; }

   if ((UtilityData(theEnv)->EphemeralItemSize + SIZE_INCREMENT) > UtilityData(theEnv)->CurrentEphemeralSizeMax)
     { UtilityData(theEnv)->CurrentEphemeralSizeMax = UtilityData(theEnv)->EphemeralItemSize + SIZE_INCREMENT; }

   /*===============================================================*/
   /* Remember the evaluation depth at which garbage collection was */
   /* last performed. This information is used for resetting the    */
   /* ephemeral count and size numbers used by the heuristics.      */
   /*===============================================================*/

   UtilityData(theEnv)->LastEvaluationDepth = EvaluationData(theEnv)->CurrentEvaluationDepth;
  }

/***************************************************/
/* AddCleanupFunction: Adds a function to the list */
/*   of functions called to perform cleanup such   */
/*   as returning free memory to the memory pool.  */
/***************************************************/
globle intBool AddCleanupFunction(
  void *theEnv,
  char *name,
  void (*theFunction)(void *),
  int priority)
  {
   return(AddCPFunction(theEnv,name,theFunction,priority,&UtilityData(theEnv)->ListOfCleanupFunctions,TRUE));
  }

#if (! ENVIRONMENT_API_ONLY) && ALLOW_ENVIRONMENT_GLOBALS
/****************************************************/
/* AddPeriodicFunction: Adds a function to the list */
/*   of functions called to handle periodic tasks.  */
/****************************************************/
globle intBool AddPeriodicFunction(
  char *name,
  void (*theFunction)(void),
  int priority)
  {
   void *theEnv;
   
   theEnv = GetCurrentEnvironment();
   
   return(AddCPFunction(theEnv,name,(void (*)(void *)) theFunction,priority,
                        &UtilityData(theEnv)->ListOfPeriodicFunctions,FALSE));
  }
#endif

/*******************************************************/
/* EnvAddPeriodicFunction: Adds a function to the list */
/*   of functions called to handle periodic tasks.     */
/*******************************************************/
globle intBool EnvAddPeriodicFunction(
  void *theEnv,
  char *name,
  void (*theFunction)(void *),
  int priority)
  {
   return(AddCPFunction(theEnv,name,theFunction,priority,&UtilityData(theEnv)->ListOfPeriodicFunctions,TRUE));
  }

/**********************************/
/* AddCPFunction: Adds a function */
/*   to a list of functions.      */
/**********************************/
static intBool AddCPFunction(
  void *theEnv,
  char *name,
  void (*theFunction)(void *),
  int priority,
  struct cleanupFunction **head,
  intBool environmentAware)
  {
   struct cleanupFunction *newPtr, *currentPtr, *lastPtr = NULL;

   newPtr = get_struct(theEnv,cleanupFunction);

   newPtr->name = name;
   newPtr->ip = theFunction;
   newPtr->priority = priority;
   newPtr->environmentAware = (short) environmentAware;

   if (*head == NULL)
     {
      newPtr->next = NULL;
      *head = newPtr;
      return(1);
     }

   currentPtr = *head;
   while ((currentPtr != NULL) ? (priority < currentPtr->priority) : FALSE)
     {
      lastPtr = currentPtr;
      currentPtr = currentPtr->next;
     }

   if (lastPtr == NULL)
     {
      newPtr->next = *head;
      *head = newPtr;
     }
   else
     {
      newPtr->next = currentPtr;
      lastPtr->next = newPtr;
     }

   return(1);
  }

/*******************************************************/
/* RemoveCleanupFunction: Removes a function from the  */
/*   list of functions called to perform cleanup such  */
/*   as returning free memory to the memory pool.      */
/*******************************************************/
globle intBool RemoveCleanupFunction(
  void *theEnv,
  char *name)
  {
   return(RemoveCPFunction(theEnv,name,&UtilityData(theEnv)->ListOfCleanupFunctions));
  }

/**********************************************************/
/* EnvRemovePeriodicFunction: Removes a function from the */
/*   list of functions called to handle periodic tasks.   */
/**********************************************************/
globle intBool EnvRemovePeriodicFunction(
  void *theEnv,
  char *name)
  {
   return(RemoveCPFunction(theEnv,name,&UtilityData(theEnv)->ListOfPeriodicFunctions));
  }

/****************************************/
/* RemoveCPFunction: Removes a function */
/*   from a list of functions.          */
/****************************************/
static intBool RemoveCPFunction(
  void *theEnv,
  char *name,
  struct cleanupFunction **head)
  {
   struct cleanupFunction *currentPtr, *lastPtr;

   lastPtr = NULL;
   currentPtr = *head;

   while (currentPtr != NULL)
     {
      if (strcmp(name,currentPtr->name) == 0)
        {
         if (lastPtr == NULL)
           { *head = currentPtr->next; }
         else
           { lastPtr->next = currentPtr->next; }
         rtn_struct(theEnv,cleanupFunction,currentPtr);
         return(TRUE);
        }
      lastPtr = currentPtr;
      currentPtr = currentPtr->next;
     }

   return(FALSE);
  }

/*****************************************************/
/* StringPrintForm: Generates printed representation */
/*   of a string. Replaces / with // and " with /".  */
/*****************************************************/
globle char *StringPrintForm(
  void *theEnv,
  char *str)
  {
   int i = 0, pos = 0;
   unsigned max = 0;
   char *theString = NULL;
   void *thePtr;

   theString = ExpandStringWithChar(theEnv,'"',theString,&pos,&max,max+80);
   while (str[i] != EOS)
     {
      if ((str[i] == '"') || (str[i] == '\\'))

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -