struct NB_SENTENCE *nbSentenceNew(NB_Facet *facet,NB_Term *term,NB_List *args) { NB_Sentence *sentence,**sentenceP; NB_Hash *hash=nb_SentenceType->hash; uint32_t hashcode; unsigned long h,*l,*r,zero=0; if(trace) outMsg(0,'T',"nbSentenceNew: called"); l=(unsigned long *)&term; if(args) r=(unsigned long *)&args; else r=&zero; h=((*l>>3)+(*r>>3)); h+=(h>>3); hashcode=h; sentenceP=(NB_Sentence **)&(hash->vect[hashcode&hash->mask]); for(sentence=*sentenceP; sentence!=NULL; sentence=*sentenceP) { if(sentence->term==term && sentence->facet==facet && sentence->args==args) return(sentence); sentenceP=(NB_Sentence **)&sentence->cell.object.next; } sentence=(NB_Sentence *)nbCellNew(nb_SentenceType,NULL,sizeof(NB_Sentence)); sentence->facet=facet; // don't grab because it is a permenant object sentence->term=grabObject(term); if(args) sentence->args=grabObject(args); else sentence->args=NULL; sentence->cell.object.hashcode=hashcode; sentence->cell.object.next=(NB_Object *)*sentenceP; *sentenceP=sentence; hash->objects++; if(hash->objects>=hash->limit) nbHashGrow(&nb_SentenceType->hash); if(args) sentence->cell.level=args->cell.level+1; else sentence->cell.level=1; sentence->cell.object.value=nb_Disabled; return(sentence); }
// Add an assertion to an assertion list int nbAssertionAddTermValue(nbCELL context,nbSET *set,nbCELL term,nbCELL cell){ NB_Link *entry; NB_Object *object; object=(NB_Object *)useCondition(assertTypeVal,term,cell); if((entry=nb_LinkFree)==NULL) entry=(NB_Link *)nbAlloc(sizeof(NB_Link)); else nb_LinkFree=entry->next; entry->object=(NB_Object *)grabObject(object); entry->next=*set; *set=entry; return(0); }
static void pullObjectFromPalette(cpShape *shape) { domino_t **dom; cpBody *body; palette_object_t *palObj; palObj = (palette_object_t *)shape->data; g_Dominoes[dominoIndex] = createDomino(atlMouseClickPos(), palObj); dom = &g_Dominoes[dominoIndex++]; (*dom)->my_index = dominoIndex-1; body = (*dom)->body; cpBodyResetForces(body); cpBodySetMoment(body, INFINITY); body->w_limit = 0.0f; grabObject(body); }
void handleEditor(void) { int dir, i; cpVect maxv, minv, mousePos; palette_object_t *tmp; cpConstraint *mouseJoint; static cpShape *clickShape = NULL; static bool canRotate = false; static cpShape *controlPoint = NULL; unsigned int w, h; mouseJoint = atlMouseJoint(); if (atlLeftMouseDown()) { clickShape = cpSpacePointQueryFirst(g_Space, atlMouseClickPos(), GRABABLE_MASK_BIT, CP_NO_GROUP); if (clickShape && !mouseJoint) { if (clickShape->collision_type == PALETTE_TYPE) { pullObjectFromPalette(clickShape); } else if (clickShape->collision_type == CONTROL_POINT_TYPE) { controlPoint = clickShape; } else { grabObject(clickShape->body); } } } else { controlPoint = NULL; if (mouseJoint) { atlRemoveMouseJoint(g_Space); } } if (controlPoint) pullControlPoint(controlPoint); if (isKeyPressed(KEY_SPACE) && mouseJoint && canRotate) { canRotate = false; cpBodySetAngle(mouseJoint->b, cpBodyGetAngle(mouseJoint->b)+45.0f*(M_PI/180)); } else if (!isKeyPressed(KEY_SPACE)) { canRotate = true; } w = atlWindowWidth(); h = atlWindowHeight(); maxv = atlMouseToSpace(w, h); minv = cpv(maxv.x-w, maxv.y+h); mousePos = atlMousePos(); dir = 0; /* allow the mouse to scroll the screen at the edges of the X-axis. clamp it * to maxv.x and minv.x so the mouse being outside the app window doesn't * cause side scrolling inadvertently */ if (isKeyPressed(KEY_RIGHT) || (mousePos.x > maxv.x - 15 && mousePos.x < maxv.x)) dir = 1; if (isKeyPressed(KEY_LEFT) || (mousePos.x < minv.x + 15 && mousePos.x > minv.x)) dir = -1; /* when the editorBody is positioned at (0, 0) it can't move left any more */ if (editorBody->p.x < 0) { dir = 0; editorBody->p.x = 0; } if (dir) { editorBody->v = cpvadd(editorBody->v, cpvmult(cpv(1, 0), 30.0f*dir)); cpBodyActivate(editorBody); } else { editorBody->v = cpvzero; /* recalculate static palette objects' positions */ for (i = 0; i < MAX_PALETTE_SHAPES; ++i) { tmp = paletteObjects[i]; if (tmp) { tmp->body->p = cpv(minv.x+25, minv.y-(45*(i+1))); } } cpSpaceRehashStatic(g_Space); } }
/* * Apply rule assertions * * mode=0 - assert * mode=1 - alert * mode=2 - default (only set if unknown) */ void nbAssert(nbCELL context,nbSET member,int mode){ //struct ASSERTION *assertion,*target; struct ASSERTION *assertion; NB_Sentence *sentence; NB_Term *term; NB_Node *node,*contextNode; NB_Skill *skill; NB_Facet *facet; NB_List *arglist; NB_Object *object; NB_Link *transientRoot=NULL,*transientLink,**transientLinkP,**transientNextP=&transientRoot; if(trace) outMsg(0,'T',"assert() called"); contextNode=(NB_Node *)((NB_Term *)context)->def; while(member!=NULL){ assertion=(struct ASSERTION *)member->object; object=assertion->object; term=(NB_Term *)assertion->target; if(assertion->target->type==termType){ // 2011-03-19 eat - don't assert if default mode and value is not unknown if(mode&2 && term->def!=nb_Unknown); else if(assertion->cell.object.type==assertTypeDef) nbTermAssign(term,object); else if(object->value==nb_Disabled){ nbTermAssign(term,object->type->compute(object)); dropObject(term->def); /* 2004/08/28 eat */ } else nbTermAssign(term,object->value); //if(mode==1 && term->cell.mode&NB_CELL_MODE_TRANSIENT){ // switch a cell flag to identify transient term if(mode==1 && assertion->cell.mode&NB_CELL_MODE_TRANSIENT){ // Handle transient assertion // remove from old list for(transientLinkP=&contextNode->transientLink;*transientLinkP!=NULL && (*transientLinkP)->object!=(NB_Object *)term;transientLinkP=&(*transientLinkP)->next); if(*transientLinkP!=NULL){ // found it, so remove and reuse transientLink=*transientLinkP; *transientLinkP=transientLink->next; transientLink->next=NULL; } else{ // not found, so create new if((transientLink=nb_LinkFree)==NULL) transientLink=nbAlloc(sizeof(NB_Link)); else nb_LinkFree=transientLink->next; transientLink->next=NULL; transientLink->object=(NB_Object *)term; // we don't grab here, but an undefine of transient term must remove from this list } // insert in new list *transientNextP=transientLink; transientNextP=&(transientLink->next); } } else if(assertion->target->type==nb_SentenceType){ if(assertion->cell.object.type==assertTypeVal){ if(object->value==nb_Disabled) object=object->type->compute(object); else object=(NB_Object *)grabObject(object->value); /* 2004/08/28 eat - grab added */ } //else if(assertion->cell.object.type!=assertTypeDef){ else if(assertion->cell.object.type==assertTypeDef){ outMsg(0,'L',"Cell definition assertion not support for node %s",term->word->value); return; } sentence=(NB_Sentence *)assertion->target; term=sentence->term; node=(NB_Node *)term->def; if(node->cell.object.type!=nb_NodeType){ outMsg(0,'E',"Term %s not defined as node",term->word->value); dropObject(object); /* 2004/08/28 eat */ return; } if((skill=node->skill)==NULL){ outMsg(0,'E',"Node %s does not have an assertion method.",term->word->value); dropObject(object); return; } facet=sentence->facet; if(sentence->args) arglist=(NB_List *)grabObject(sentence->args); else arglist=NULL; if(mode&1)(*facet->alert)(term,skill->handle,node->knowledge,(NB_Cell *)arglist,(NB_Cell *)object); else (*facet->assert)(term,skill->handle,node->knowledge,(NB_Cell *)arglist,(NB_Cell *)object); dropObject(arglist); dropObject(object); /* 2004/08/28 eat */ nbCellPublish((NB_Cell *)term->def); nbCellPublish((NB_Cell *)term); } member=member->next; } if(mode==1){ // for alerts // Reset to Unknown the event transient terms from the last alert not set this time. for(transientLink=contextNode->transientLink;transientLink!=NULL;transientLink=contextNode->transientLink){ term=(NB_Term *)transientLink->object; nbTermAssign(term,nb_Unknown); // reset event cell to Unknown contextNode->transientLink=transientLink->next; transientLink->next=nb_LinkFree; nb_LinkFree=transientLink; } contextNode->transientLink=transientRoot; // Save list of event transient terms in this alert } }