void file_load(fpath filename) { filename = asset_map_filename(filename); if (dict_contains(asset_dict, filename.ptr)) { error("Asset '%s' already loaded", filename.ptr); } fpath ext; SDL_PathFileExtension(ext.ptr, filename.ptr); for(int i=0; i < num_asset_handlers; i++) { asset_handler handler = asset_handlers[i]; if (strcmp(ext.ptr, handler.extension) == 0) { debug("Loading: '%s'", filename.ptr); asset* a = handler.load_func(filename.ptr); dict_set(asset_dict, filename.ptr, a); break; } } }
char variable_exists(char*name) { return dict_contains(state->vars, name); }
dnode_t *dict_delete(dict_t *dict, dnode_t *target) { dnode_t *nil = dict_nil(dict), *child, *delparent = target->parent; /* basic deletion */ assert (!dict_isempty(dict)); assert (dict_contains(dict, target)); /* * If the node being deleted has two children, then we replace it with its * successor (i.e. the leftmost node in the right subtree.) By doing this, * we avoid the traditional algorithm under which the successor's key and * value *only* move to the deleted node and the successor is spliced out * from the tree. We cannot use this approach because the user may hold * pointers to the successor, or nodes may be inextricably tied to some * other structures by way of embedding, etc. So we must splice out the * node we are given, not some other node, and must not move contents from * one node to another behind the user's back. */ if (target->left != nil && target->right != nil) { dnode_t *next = dict_next(dict, target); dnode_t *nextparent = next->parent; dnode_color_t nextcolor = next->color; assert (next != nil); assert (next->parent != nil); assert (next->left == nil); /* * First, splice out the successor from the tree completely, by * moving up its right child into its place. */ child = next->right; child->parent = nextparent; if (nextparent->left == next) { nextparent->left = child; } else { assert (nextparent->right == next); nextparent->right = child; } /* * Now that the successor has been extricated from the tree, install it * in place of the node that we want deleted. */ next->parent = delparent; next->left = target->left; next->right = target->right; next->left->parent = next; next->right->parent = next; next->color = target->color; target->color = nextcolor; if (delparent->left == target) { delparent->left = next; } else { assert (delparent->right == target); delparent->right = next; } } else { assert (target != nil); assert (target->left == nil || target->right == nil); child = (target->left != nil) ? target->left : target->right; child->parent = delparent = target->parent; if (target == delparent->left) { delparent->left = child; } else { assert (target == delparent->right); delparent->right = child; } } target->parent = NULL; target->right = NULL; target->left = NULL; dict->nodecount--; assert (verify_bintree(dict)); /* red-black adjustments */ if (target->color == dnode_black) { dnode_t *parent, *sister; dict_root(dict)->color = dnode_red; while (child->color == dnode_black) { parent = child->parent; if (child == parent->left) { sister = parent->right; assert (sister != nil); if (sister->color == dnode_red) { sister->color = dnode_black; parent->color = dnode_red; rotate_left(parent); sister = parent->right; assert (sister != nil); } if (sister->left->color == dnode_black && sister->right->color == dnode_black) { sister->color = dnode_red; child = parent; } else { if (sister->right->color == dnode_black) { assert (sister->left->color == dnode_red); sister->left->color = dnode_black; sister->color = dnode_red; rotate_right(sister); sister = parent->right; assert (sister != nil); } sister->color = parent->color; sister->right->color = dnode_black; parent->color = dnode_black; rotate_left(parent); break; } } else { /* symmetric case: child == child->parent->right */ assert (child == parent->right); sister = parent->left; assert (sister != nil); if (sister->color == dnode_red) { sister->color = dnode_black; parent->color = dnode_red; rotate_right(parent); sister = parent->left; assert (sister != nil); } if (sister->right->color == dnode_black && sister->left->color == dnode_black) { sister->color = dnode_red; child = parent; } else { if (sister->left->color == dnode_black) { assert (sister->right->color == dnode_red); sister->right->color = dnode_black; sister->color = dnode_red; rotate_left(sister); sister = parent->left; assert (sister != nil); } sister->color = parent->color; sister->left->color = dnode_black; parent->color = dnode_black; rotate_right(parent); break; } } } child->color = dnode_black; dict_root(dict)->color = dnode_black; } assert (dict_verify(dict)); return target; }
void dict_insert(dict_t *dict, dnode_t *node, const void *key) { dnode_t *where = dict_root(dict), *nil = dict_nil(dict); dnode_t *parent = nil, *uncle, *grandpa; int result = -1; node->key = key; assert (!dict_isfull(dict)); assert (!dict_contains(dict, node)); assert (!dnode_is_in_a_dict(node)); /* basic binary tree insert */ while (where != nil) { parent = where; result = dict->compare(key, where->key); /* trap attempts at duplicate key insertion unless it's explicitly allowed */ assert (dict->dupes || result != 0); if (result < 0) where = where->left; else where = where->right; } assert (where == nil); if (result < 0) parent->left = node; else parent->right = node; node->parent = parent; node->left = nil; node->right = nil; dict->nodecount++; /* red black adjustments */ node->color = dnode_red; while (parent->color == dnode_red) { grandpa = parent->parent; if (parent == grandpa->left) { uncle = grandpa->right; if (uncle->color == dnode_red) { /* red parent, red uncle */ parent->color = dnode_black; uncle->color = dnode_black; grandpa->color = dnode_red; node = grandpa; parent = grandpa->parent; } else { /* red parent, black uncle */ if (node == parent->right) { rotate_left(parent); parent = node; assert (grandpa == parent->parent); /* rotation between parent and child preserves grandpa */ } parent->color = dnode_black; grandpa->color = dnode_red; rotate_right(grandpa); break; } } else { /* symmetric cases: parent == parent->parent->right */ uncle = grandpa->left; if (uncle->color == dnode_red) { parent->color = dnode_black; uncle->color = dnode_black; grandpa->color = dnode_red; node = grandpa; parent = grandpa->parent; } else { if (node == parent->left) { rotate_right(parent); parent = node; assert (grandpa == parent->parent); } parent->color = dnode_black; grandpa->color = dnode_red; rotate_left(grandpa); break; } } } dict_root(dict)->color = dnode_black; assert (dict_verify(dict)); }
bool file_isloaded(fpath path) { path = asset_map_filename(path); return dict_contains(asset_dict, path.ptr); }
const void * fc_solve_kaz_tree_insert(dict_t *dict, dnode_t *node, const void *key) { dnode_t *where = dict_root(dict), *nil = dict_nil(dict); dnode_t *parent = nil, *uncle, *grandpa; int result = -1; node->key = key; assert (!dict_isfull(dict)); assert (!dict_contains(dict, node)); assert (!dnode_is_in_a_dict(node)); /* basic binary tree insert */ while (where != nil) { parent = where; result = dict->compare(key, where->key, dict->context); /* We are remming it out because instead of duplicating the key * we return the existing key. -- Shlomi Fish, fc-solve. * */ #if 0 /* trap attempts at duplicate key insertion unless it's explicitly allowed */ assert (dict->dupes || result != 0); #endif if (result == 0) { return where->dict_key; } else if (result < 0) { where = where->left; } else { where = where->right; } } assert (where == nil); if (result < 0) parent->left = node; else parent->right = node; node->parent = parent; node->left = nil; node->right = nil; #ifdef NO_FC_SOLVE dict->nodecount++; #endif /* red black adjustments */ node->color = dnode_red; while (parent->color == dnode_red) { grandpa = parent->parent; if (parent == grandpa->left) { uncle = grandpa->right; if (uncle->color == dnode_red) { /* red parent, red uncle */ parent->color = dnode_black; uncle->color = dnode_black; grandpa->color = dnode_red; node = grandpa; parent = grandpa->parent; } else { /* red parent, black uncle */ if (node == parent->right) { rotate_left(parent); parent = node; assert (grandpa == parent->parent); /* rotation between parent and child preserves grandpa */ } parent->color = dnode_black; grandpa->color = dnode_red; rotate_right(grandpa); break; } } else { /* symmetric cases: parent == parent->parent->right */ uncle = grandpa->left; if (uncle->color == dnode_red) { parent->color = dnode_black; uncle->color = dnode_black; grandpa->color = dnode_red; node = grandpa; parent = grandpa->parent; } else { if (node == parent->left) { rotate_right(parent); parent = node; assert (grandpa == parent->parent); } parent->color = dnode_black; grandpa->color = dnode_red; rotate_left(grandpa); break; } } } dict_root(dict)->color = dnode_black; assert (dict_verify(dict)); return NULL; }