static PropPtr remove_propnode(char *key, PropPtr * root) { PropPtr save; PropPtr tmp; PropPtr avl = *root; int cmpval; save = avl; if (avl) { cmpval = Comparator(key, PropName(avl)); if (cmpval < 0) { save = remove_propnode(key, &AVL_LF(avl)); } else if (cmpval > 0) { save = remove_propnode(key, &AVL_RT(avl)); } else if (!(AVL_LF(avl))) { avl = AVL_RT(avl); } else if (!(AVL_RT(avl))) { avl = AVL_LF(avl); } else { tmp = remove_propnode(PropName(getmax(AVL_LF(avl))), &AVL_LF(avl)); if (!tmp) abort(); /* this shouldn't be possible. */ AVL_LF(tmp) = AVL_LF(avl); AVL_RT(tmp) = AVL_RT(avl); avl = tmp; } if (save) { AVL_LF(save) = NULL; AVL_RT(save) = NULL; } *root = balance_node(avl); } return save; }
PropPtr next_prop(PropPtr list, PropPtr prop, char *name) { PropPtr p = prop; if (!p || !(p = next_node(list, PropName(p)))) return ((PropPtr) 0); strcpy(name, PropName(p)); return (p); }
/** * This creates a new node in the AVL then returns the created node * so that you might populate it with data. If the key already * exists, then the existing node is returned. * * @param avl the AVL to add a property to. * @param key the key to add to the AVL. * * @return the newly created AVL node. */ PropPtr new_prop(PropPtr *avl, char *key) { PropPtr ret; register PropPtr p = *avl; register int cmp; static short balancep; if (p) { cmp = strcasecmp(key, PropName(p)); if (cmp > 0) { ret = new_prop(&(p->right), key); } else if (cmp < 0) { ret = new_prop(&(p->left), key); } else { balancep = 0; return (p); } if (balancep) { *avl = balance_node(p); } return ret; } else { p = *avl = alloc_propnode(key); balancep = 1; return (p); } }
static PropPtr insert(char *key, PropPtr * avl) { PropPtr ret; register PropPtr p = *avl; register int cmp; static short balancep; if (p) { cmp = Comparator(key, PropName(p)); if (cmp > 0) { ret = insert(key, &(AVL_RT(p))); } else if (cmp < 0) { ret = insert(key, &(AVL_LF(p))); } else { balancep = 0; return (p); } if (balancep) { *avl = balance_node(p); } return ret; } else { p = *avl = alloc_propnode(key); balancep = 1; return (p); } }
/** * Calculates the size of the given property directory AVL list. This * will iterate over the entire structure to give the entire size. It * is the low level equivalent of size_properties * * @see size_properties * * @param avl the Property directory AVL to check * @return the size of the loaded properties in memory -- this does NOT * do any diskbase loading. */ size_t size_proplist(PropPtr avl) { size_t bytes = 0; if (!avl) return 0; bytes += sizeof(struct plist); bytes += strlen(PropName(avl)); if (!(PropFlags(avl) & PROP_ISUNLOADED)) { switch (PropType(avl)) { case PROP_STRTYP: bytes += strlen(PropDataStr(avl)) + 1; break; case PROP_LOKTYP: bytes += size_boolexp(PropDataLok(avl)); break; default: break; } } bytes += size_proplist(avl->left); bytes += size_proplist(avl->right); bytes += size_proplist(PropDir(avl)); return bytes; }
/* removes property list --- if it's not there then ignore */ void remove_property_list(dbref player, int all) { PropPtr l; PropPtr p; PropPtr n; /* if( tp_db_readonly ) return; *//* Why did we remove this? */ #ifdef DISKBASE fetchprops(player); #endif if ((l = DBFETCH(player)->properties)) { p = first_node(l); while (p) { n = next_node(l, PropName(p)); remove_proplist_item(player, p, all); l = DBFETCH(player)->properties; p = n; } } #ifdef DISKBASE dirtyprops(player); #endif DBDIRTY(player); }
static void unparse_boolexp1(dbref player, struct boolexp * b, boolexp_type outer_type, int fullname) { if ((buftop - boolexp_buf) > (BUFFER_LEN / 2)) return; if (b == TRUE_BOOLEXP) { strcpy(buftop, "*UNLOCKED*"); buftop += strlen(buftop); } else { switch (b->type) { case BOOLEXP_AND: if (outer_type == BOOLEXP_NOT) { *buftop++ = '('; } unparse_boolexp1(player, b->sub1, b->type, fullname); *buftop++ = AND_TOKEN; unparse_boolexp1(player, b->sub2, b->type, fullname); if (outer_type == BOOLEXP_NOT) { *buftop++ = ')'; } break; case BOOLEXP_OR: if (outer_type == BOOLEXP_NOT || outer_type == BOOLEXP_AND) { *buftop++ = '('; } unparse_boolexp1(player, b->sub1, b->type, fullname); *buftop++ = OR_TOKEN; unparse_boolexp1(player, b->sub2, b->type, fullname); if (outer_type == BOOLEXP_NOT || outer_type == BOOLEXP_AND) { *buftop++ = ')'; } break; case BOOLEXP_NOT: *buftop++ = '!'; unparse_boolexp1(player, b->sub1, b->type, fullname); break; case BOOLEXP_CONST: if (fullname) { #ifndef SANITY strcpy(buftop, unparse_object(player, b->thing)); #endif } else { sprintf(buftop, "#%d", b->thing); } buftop += strlen(buftop); break; case BOOLEXP_PROP: strcpy(buftop, PropName(b->prop_check)); strcat(buftop, ":"); if (PropType(b->prop_check) == PROP_STRTYP) strcat(buftop, PropDataStr(b->prop_check)); buftop += strlen(buftop); break; default: abort(); /* bad type */ break; } } }
PropPtr next_node(PropPtr ptr, char *name) { PropPtr from; int cmpval; if (!ptr) return NULL; if (!name || !*name) return (PropPtr) NULL; cmpval = Comparator(name, PropName(ptr)); if (cmpval < 0) { from = next_node(AVL_LF(ptr), name); if (from) return from; return ptr; } else if (cmpval > 0) { return next_node(AVL_RT(ptr), name); } else if (AVL_RT(ptr)) { from = AVL_RT(ptr); while (AVL_LF(from)) from = AVL_LF(from); return from; } else { return NULL; } }
/** * next_node locates and returns the next node in the AVL (prop directory) * or NULL if there is no more. It is used for traversing a prop directory. * * @param ptr the AVL to navigate * @param name The "previous path" ... what is returned is the next path * after this one * @return the property we found, or NULL */ PropPtr next_node(PropPtr ptr, char *name) { PropPtr from; int cmpval; if (!ptr) return NULL; if (!name || !*name) return (PropPtr) NULL; cmpval = strcasecmp(name, PropName(ptr)); if (cmpval < 0) { from = next_node(ptr->left, name); if (from) return from; return ptr; } else if (cmpval > 0) { return next_node(ptr->right, name); } else if (ptr->right) { from = ptr->right; while (from->left) from = from->left; return from; } else { return NULL; } }
void __fastcall TPieEditor::EditProperty(const _di_IProperty Prop, bool& Continue) { String PropName(Prop->GetName()); if (PropName.CompareIC("ANGLES") == 0){ Prop->Edit(); Continue = false; } }
/** * Remove a propnode named 'key' from the AVL root 'root'. This function * is recursive. * * The node (removed from the AVL structure) is returned, or NULL if it * was not found. * * @private * @param key the prop name to remove * @param root the root node to start the removal process from * * @return the removed node - you should probably free it with free_propnode */ static PropPtr remove_propnode(char *key, PropPtr * root) { PropPtr save; PropPtr tmp; PropPtr avl = *root; int cmpval; save = avl; if (avl) { cmpval = strcasecmp(key, PropName(avl)); if (cmpval < 0) { save = remove_propnode(key, &(avl->left)); } else if (cmpval > 0) { save = remove_propnode(key, &(avl->right)); } else if (!(avl->left)) { avl = avl->right; } else if (!(avl->right)) { avl = avl->left; } else { tmp = remove_propnode(PropName(getmax(avl->left)), &(avl->left)); if (!tmp) { /* this shouldn't be possible. */ panic("remove_propnode() returned NULL !"); } tmp->left = avl->left; tmp->right = avl->right; avl = tmp; } if (save) { save->left = NULL; save->right = NULL; } *root = balance_node(avl); } return save; }
char * next_prop_name(dbref player, char *outbuf, char *name) { char *ptr; char buf[BUFFER_LEN]; PropPtr p, l; #ifdef DISKBASE fetchprops(player); #endif strcpy(buf, name); if (!*name || name[strlen(name) - 1] == PROPDIR_DELIMITER) { l = DBFETCH(player)->properties; p = propdir_first_elem(l, buf); if (!p) { *outbuf = '\0'; return NULL; } strcat(strcpy(outbuf, name), PropName(p)); } else { /* if (!(get_property(player,name))) { *outbuf = '\0'; return NULL; } */ l = DBFETCH(player)->properties; p = propdir_next_elem(l, buf); if (!p) { *outbuf = '\0'; return NULL; } strcpy(outbuf, name); ptr = rindex(outbuf, PROPDIR_DELIMITER); if (!ptr) ptr = outbuf; *(ptr++) = PROPDIR_DELIMITER; strcpy(ptr, PropName(p)); } return outbuf; }
/* return a pointer to the first property in a propdir and duplicates the property name into 'name'. returns 0 if the property list is empty or does not exist. */ PropPtr first_prop_nofetch(dbref player, const char *dir, PropPtr *list, char *name) { char buf[BUFFER_LEN]; PropPtr p; if (dir) { while (*dir && *dir == PROPDIR_DELIMITER) { dir++; } } if (!dir || !*dir) { *list = DBFETCH(player)->properties; p = first_node(*list); if (p) { strcpy(name, PropName(p)); } else { *name = '\0'; } return (p); } strcpy(buf, dir); *list = p = propdir_get_elem(DBFETCH(player)->properties, buf); if (!p) { *name = '\0'; return NULL; } *list = PropDir(p); p = first_node(*list); if (p) { strcpy(name, PropName(p)); } else { *name = '\0'; } return (p); }
static PropPtr find(char *key, PropPtr avl) { int cmpval; while (avl) { cmpval = Comparator(key, PropName(avl)); if (cmpval > 0) { avl = AVL_RT(avl); } else if (cmpval < 0) { avl = AVL_LF(avl); } else { break; } } return avl; }
/** * This finds a prop named 'key' in the AVL proplist 'avl'. It is basically * a primitive for looking up items in the AVLs. * * @param avl the AVL to search * @param key the key to look up * * @return the found node, or NULL if not found. */ PropPtr locate_prop(PropPtr avl, char *key) { int cmpval; while (avl) { cmpval = strcasecmp(key, PropName(avl)); if (cmpval > 0) { avl = avl->right; } else if (cmpval < 0) { avl = avl->left; } else { break; } } return avl; }
/* copies properties */ void copy_proplist(dbref obj, PropPtr * nu, PropPtr old) { PropPtr p; if (old) { #ifdef DISKBASE propfetch(obj, old); #endif p = new_prop(nu, PropName(old)); SetPFlagsRaw(p, PropFlagsRaw(old)); switch (PropType(old)) { case PROP_STRTYP: SetPDataStr(p, alloc_string(PropDataStr(old))); break; case PROP_LOKTYP: if (PropFlags(old) & PROP_ISUNLOADED) { SetPDataLok(p, TRUE_BOOLEXP); SetPFlags(p, (PropFlags(p) & ~PROP_ISUNLOADED)); } else { SetPDataLok(p, copy_bool(PropDataLok(old))); } break; case PROP_DIRTYP: SetPDataVal(p, 0); break; case PROP_FLTTYP: SetPDataFVal(p, PropDataFVal(old)); break; default: SetPDataVal(p, PropDataVal(old)); break; } copy_proplist(obj, &PropDir(p), PropDir(old)); copy_proplist(obj, &AVL_LF(p), AVL_LF(old)); copy_proplist(obj, &AVL_RT(p), AVL_RT(old)); /* copy_proplist(obj, nu, AVL_LF(old)); copy_proplist(obj, nu, AVL_RT(old)); */ } }
void db_dump_props_rec(dbref obj, FILE * f, const char *dir, PropPtr p) { char buf[BUFFER_LEN]; #ifdef DISKBASE int tpos = 0; int flg; short wastouched = 0; #endif if (!p) return; db_dump_props_rec(obj, f, dir, AVL_LF(p)); #ifdef DISKBASE if (tp_diskbase_propvals) { tpos = ftell(f); wastouched = (PropFlags(p) & PROP_TOUCHED); } if (propfetch(obj, p)) { fseek(f, 0L, 2); } #endif db_putprop(f, dir, p); #ifdef DISKBASE if (tp_diskbase_propvals && !wastouched) { if (PropType(p) == PROP_STRTYP || PropType(p) == PROP_LOKTYP) { flg = PropFlagsRaw(p) | PROP_ISUNLOADED; clear_propnode(p); SetPFlagsRaw(p, flg); SetPDataVal(p, tpos); } } #endif if (PropDir(p)) { sprintf(buf, "%s%s%c", dir, PropName(p), PROPDIR_DELIMITER); db_dump_props_rec(obj, f, buf, PropDir(p)); } db_dump_props_rec(obj, f, dir, AVL_RT(p)); }
/** * This allocates a property node for use in the property AVL tree. The * note has the given name (memory is copied over) and is set dirty, but * otherwise is a blank slate ready to be added to the AVL. * * Chances are, you do not want to use this method. It is exposed because * it is used in boolexp.c and props.c * * @internal * @param name String property name (memory will be copied) * @return allocated PropPtr AVL node. */ PropPtr alloc_propnode(const char *name) { PropPtr new_node; size_t nlen = strlen(name); new_node = malloc(sizeof(struct plist) + nlen); if (!new_node) { fprintf(stderr, "alloc_propnode(): Out of Memory!\n"); abort(); } new_node->left = NULL; new_node->right = NULL; new_node->height = 1; strcpyn(PropName(new_node), nlen + 1, name); SetPFlagsRaw(new_node, PROP_DIRTYP); SetPDataVal(new_node, 0); SetPDir(new_node, NULL); return new_node; }
/* path is the name of the property to delete */ PropPtr propdir_delete_elem(PropPtr root, char *path) { PropPtr p; char *n; if (!root) return (NULL); while (*path && *path == PROPDIR_DELIMITER) path++; if (!*path) return (root); n = index(path, PROPDIR_DELIMITER); while (n && *n == PROPDIR_DELIMITER) *(n++) = '\0'; if (n && *n) { /* just another propdir in the path */ p = locate_prop(root, path); if (p && PropDir(p)) { /* yup, found the propdir */ SetPDir(p, propdir_delete_elem(PropDir(p), n)); if (!PropDir(p) && PropType(p) == PROP_DIRTYP) { root = delete_prop(&root, PropName(p)); } } /* return the updated root pntr */ return (root); } else { /* aha, we are finally to the property itself. */ p = locate_prop(root, path); if (p && PropDir(p)) { delete_proplist(PropDir(p)); } (void) delete_prop(&root, path); return (root); } }
void remove_proplist_item(dbref player, PropPtr p, int allp) { const char *ptr; /* if( tp_db_readonly ) return; *//* Why did we remove this? */ if (!p) return; ptr = PropName(p); if (!allp) { if (Prop_SeeOnly(ptr)) return; if (Prop_Hidden(ptr)) return; if (ptr[0] == '_' && ptr[1] == '\0') return; if (PropFlags(p) & PROP_SYSPERMS) return; } /* notify(player, ptr); *//* Why did we put this here? */ remove_property(player, ptr); }
TArray<AActor*> UJsonSpawnLibrary::SpawnActorsFromJson(FString Json) { TArray<AActor*> Result; TSharedRef<TJsonReader<TCHAR>> JsonReader = TJsonReaderFactory<>::Create(Json); EJsonNotation Notation; if(!( (JsonReader->ReadNext(Notation) && (EJsonNotation::ObjectStart == Notation)) && (JsonReader->ReadNext(Notation) && (EJsonNotation::ArrayStart == Notation)) )) { UE_LOG(LogJsonSpawn, Warning, TEXT("Invalid JSON Format")); return Result; } AActor* SpawnedActor = NULL; while(JsonReader->ReadNext(Notation)) { switch(Notation) { case EJsonNotation::Boolean: { FName PropName(*JsonReader->GetIdentifier()); FString PropType = GetPropertyType(SpawnedActor, PropName); if(0 == FString(TEXT("bool")).Compare(PropType)) { bool PropValue = JsonReader->GetValueAsBoolean(); ApplyProperyValue<bool>(SpawnedActor, PropName, PropValue); } else { UE_LOG(LogJsonSpawn, Warning, TEXT("Invalid Boolean Value [%s.%s]"), (SpawnedActor ? *SpawnedActor->GetClass()->GetName() : TEXT("None")), *PropName.ToString()); } } break; case EJsonNotation::String: { FName PropName(*JsonReader->GetIdentifier()); FString PropType = GetPropertyType(SpawnedActor, PropName); if(0 == FString(TEXT("FString")).Compare(PropType)) { FString PropValue = JsonReader->GetValueAsString(); ApplyProperyValue<FString>(SpawnedActor, PropName, PropValue); } else { if(FName(TEXT("ClassName")) == PropName) { const FString& TypeName = JsonReader->GetValueAsString(); if(!TypeName.IsEmpty()) { UClass* ClassPtr = FindObject<UClass>(ANY_PACKAGE, *TypeName); if(ClassPtr) { SpawnedActor = GWorld->SpawnActor(ClassPtr); if(NULL != SpawnedActor) { Result.Add(SpawnedActor); } else { UE_LOG(LogJsonSpawn, Warning, TEXT("Failed Spawn Actor [%s]"), *TypeName); } } else { UE_LOG(LogJsonSpawn, Warning, TEXT("Not Found Class [%s]"), *TypeName); SpawnedActor = NULL; } } } else { UE_LOG(LogJsonSpawn, Warning, TEXT("Invalid String Value [%s.%s]"), (SpawnedActor ? *SpawnedActor->GetClass()->GetName() : TEXT("None")), *PropName.ToString()); } } } break; case EJsonNotation::Number: { FName PropName(*JsonReader->GetIdentifier()); FString PropType = GetPropertyType(SpawnedActor, PropName); if(0 == FString(TEXT("int32")).Compare(PropType)) { int32 PropValue = static_cast<int32>(JsonReader->GetValueAsNumber()); ApplyProperyValue<int32>(SpawnedActor, PropName, PropValue); } else if(0 == FString(TEXT("float")).Compare(PropType)) { float PropValue = static_cast<float>(JsonReader->GetValueAsNumber()); ApplyProperyValue<float>(SpawnedActor, PropName, PropValue); } else { UE_LOG(LogJsonSpawn, Warning, TEXT("Invalid Number Value [%s.%s]"), (SpawnedActor ? *SpawnedActor->GetClass()->GetName() : TEXT("None")), *PropName.ToString()); } } break; case EJsonNotation::ArrayStart: { FName PropName(*JsonReader->GetIdentifier()); FString PropType = GetPropertyType(SpawnedActor, PropName); if(0 == FString(TEXT("FVector")).Compare(PropType)) { FVector PropValue; if(ParseVectorValue(JsonReader, PropValue)) { ApplyProperyValue<FVector>(SpawnedActor, PropName, PropValue); } else { UE_LOG(LogJsonSpawn, Warning, TEXT("Invalid Vector Value [%s.%s]"), (SpawnedActor ? *SpawnedActor->GetClass()->GetName() : TEXT("None")), *PropName.ToString()); } } else if(0 == FString(TEXT("FRotator")).Compare(PropType)) { FRotator PropValue; if(ParseRotatorValue(JsonReader, PropValue)) { ApplyProperyValue<FRotator>(SpawnedActor, PropName, PropValue); } else { UE_LOG(LogJsonSpawn, Warning, TEXT("Invalid Rotator Value [%s.%s]"), (SpawnedActor ? *SpawnedActor->GetClass()->GetName() : TEXT("None")), *PropName.ToString()); } } else { if(FName(TEXT("Location")) == PropName) { FVector PropValue; if(ParseVectorValue(JsonReader, PropValue)) { if(SpawnedActor) { SpawnedActor->SetActorLocation(PropValue); } else { UE_LOG(LogJsonSpawn, Warning, TEXT("Invalid Location. Actor hasn't spawned.")); } } else { UE_LOG(LogJsonSpawn, Warning, TEXT("Invalid Location Value [%s]"), (SpawnedActor ? *SpawnedActor->GetClass()->GetName() : TEXT("None"))); } } else if(FName(TEXT("Rotation")) == PropName) { FRotator PropValue; if(ParseRotatorValue(JsonReader, PropValue)) { if(SpawnedActor) { SpawnedActor->SetActorRotation(PropValue); } else { UE_LOG(LogJsonSpawn, Warning, TEXT("Invalid Rotation. Actor hasn't spawned.")); } } else { UE_LOG(LogJsonSpawn, Warning, TEXT("Invalid Rotaion Value [%s.%s]"), (SpawnedActor ? *SpawnedActor->GetClass()->GetName() : TEXT("None")), *PropName.ToString()); } } else if(FName(TEXT("Scale")) == PropName) { FVector PropValue; if(ParseVectorValue(JsonReader, PropValue)) { if(SpawnedActor) { SpawnedActor->SetActorScale3D(PropValue); } else { UE_LOG(LogJsonSpawn, Warning, TEXT("Invalid Scale. Actor hasn't spawned.")); } } else { UE_LOG(LogJsonSpawn, Warning, TEXT("Invalid Scale Value [%s]"), (SpawnedActor ? *SpawnedActor->GetClass()->GetName() : TEXT("None"))); } } else { UE_LOG(LogJsonSpawn, Warning, TEXT("Invalid Array Value [%s.%s]"), (SpawnedActor ? *SpawnedActor->GetClass()->GetName() : TEXT("None")), *PropName.ToString()); } } } break; case EJsonNotation::ObjectStart: case EJsonNotation::ObjectEnd: case EJsonNotation::ArrayEnd: case EJsonNotation::Null: case EJsonNotation::Error: { } break; } } return Result; }
void db_putprop(FILE * f, const char *dir, PropPtr p) { char buf[BUFFER_LEN * 2]; char fbuf[BUFFER_LEN]; char num[16]; char *ptr; const char *ptr2; if (PropType(p) == PROP_DIRTYP) return; for (ptr = buf, ptr2 = dir + 1; *ptr2;) *ptr++ = *ptr2++; for (ptr2 = PropName(p); *ptr2;) *ptr++ = *ptr2++; *ptr++ = PROP_DELIMITER; ptr2 = intostr(num, PropFlagsRaw(p) & ~(PROP_TOUCHED | PROP_ISUNLOADED | PROP_NOASCIICHK)); while (*ptr2) *ptr++ = *ptr2++; *ptr++ = PROP_DELIMITER; ptr2 = ""; switch (PropType(p)) { case PROP_INTTYP: if (!PropDataVal(p)) return; ptr2 = intostr(num, PropDataVal(p)); break; case PROP_FLTTYP: if (!PropDataFVal(p)) return; ptr2 = fltostr(fbuf, PropDataFVal(p)); break; case PROP_REFTYP: if (PropDataRef(p) == NOTHING) return; ptr2 = intostr(num, (int) PropDataRef(p)); break; case PROP_STRTYP: if (!*PropDataStr(p)) return; if (db_decompression_flag) { ptr2 = PropDataUNCStr(p); } else { ptr2 = PropDataStr(p); } break; case PROP_LOKTYP: if (PropFlags(p) & PROP_ISUNLOADED) return; if (PropDataLok(p) == TRUE_BOOLEXP) return; ptr2 = unparse_boolexp((dbref) 1, PropDataLok(p), 0); break; } while (*ptr2) if (*ptr2 != '\n') *ptr++ = *ptr2++; else { *ptr++ = '\\'; *ptr++ = 'n'; ptr2++; } *ptr++ = '\n'; *ptr++ = '\0'; if (fputs(buf, f) == EOF) { fprintf(stderr, "PANIC: Unable to write to db to write prop.\n"); abort(); } }