/** * This function explores the string 's' in order to find the longest prefix that is a key * in the string_hash. 'pos' is the current position in 's'. 'node' is the current node * in the string_hash tree. */ int get_longest_key_index_(const unichar* s,int pos,int *key_length,struct string_hash_tree_node* node) { int index=-1; if (node->value_index!=NO_VALUE_INDEX) { /* If we have a key, we check if its length is greater than the previous one, if any */ if (pos>(*key_length)) { /* If the key is the longest one we have found, we update the index, but we * don't return, since we must look for longer keys */ index=node->value_index; (*key_length)=pos; } } if (s[pos]=='\0') { /* If there is nothing more in the string, we must return */ return index; } /* If we are not at the end of 's', we look for the transition to follow */ struct string_hash_tree_transition* t=get_transition(s[pos],node->trans); if (t==NULL) { /* If there is none, we must return */ return index; } /* If there is one, we look for a longer key */ int new_index=get_longest_key_index_(s,pos+1,key_length,t->node); if (new_index!=NO_VALUE_INDEX) { /* If we have found a key, it is necessary a longer key, so we prefer it * to the previous one, if any */ return new_index; } return index; }
/** * \brief Suspends or resumes the animation. * * Nothing is done if the parameter specified does not change. * * \param suspended true to suspend the animation, false to resume it */ void Sprite::set_suspended(bool suspended) { if (suspended != this->suspended && !ignore_suspend) { this->suspended = suspended; // compte next_frame_date if the animation is being resumed if (!suspended) { uint32_t now = System::now(); next_frame_date = now + get_frame_delay(); blink_next_change_date = now; } else { blink_is_sprite_visible = true; } // Also suspend or resumed the transition effect and the movement if any. Transition* transition = get_transition(); if (transition != NULL) { transition->set_suspended(suspended); } Movement* movement = get_movement(); if (movement != NULL) { movement->set_suspended(suspended); } } }
void get_node_thai(unichar* line, int pos, struct sort_tree_node* n, unichar* real_string, struct sort_infos* inf) { if (line[pos] == '\0') { /* We are at the final node for 'line' */ n->couples = insert_string_thai(real_string, n->couples, inf); return; } /* If we are not at the end of the string 'line' */ struct sort_tree_transition* trans = get_transition(line[pos], &(n->transitions), inf); if (trans->node == NULL) { trans->node = new_sort_tree_node(); } get_node_thai(line, pos + 1, trans->node, real_string, inf); }
/** * This function explores a dictionary tree in order to insert an entry. * 'inflected' is the inflected form to insert, and 'pos' is the current position * in the string 'inflected'. 'node' is the current node in the dictionary tree. * 'infos' is used to access to constant parameters. */ static void add_entry_to_dictionary_tree(const unichar* inflected,int pos,struct dictionary_node* node, struct info* infos,int /*line*/, Abstract_allocator prv_alloc) { for (;;) { if (inflected[pos]=='\0') { /* If we have reached the end of 'inflected', then we are in the * node where the INF code must be inserted */ int N=get_value_index(infos->INF_code,infos->INF_code_list); if (node->single_INF_code_list==NULL) { /* If there is no INF code in the node, then * we add one and we return */ node->single_INF_code_list=new_list_int(N,prv_alloc); node->INF_code=N; return; } /* If there is an INF code list in the node ...*/ if (is_in_list(N,node->single_INF_code_list)) { /* If the INF code has already been taken into account for this node * (case of duplicates), we do nothing */ return; } /* Otherwise, we add it to the INF code list */ node->single_INF_code_list=head_insert(N,node->single_INF_code_list,prv_alloc); /* And we update the global INF line for this node */ node->INF_code=get_value_index_for_string_colon_string(infos->INF_code_list->value[node->INF_code],infos->INF_code,infos->INF_code_list); return; } /* If we are not at the end of 'inflected', then we look for * the correct outgoing transition and we follow it */ struct dictionary_node_transition* t=get_transition(inflected[pos],&node,prv_alloc); if (t->node==NULL) { /* We create the node if necessary */ t->node=new_dictionary_node(prv_alloc); (t->node->incoming)++; } node=t->node; pos++; } }
TITANIUM_PROPERTY_GETTER(Animation, transition) { return get_context().CreateNumber(get_transition()); }
/** * This function explore the normalization grammar to construct * the normalization tree. If the 'list' parameter is NULL, then we * are in the main call to the main graph; otherwise, we are within * a subgraph. */ void explore_normalization_fst2(Fst2* fst2,int current_state, struct normalization_tree* node, struct string_hash* tokens,const unichar* output, const Alphabet* alph,struct norm_info** list) { Fst2State state=fst2->states[current_state]; if (is_final_state(state)) { /* If we are in a final state, we behave differently if we are in a subgraph * or in the main call to the main graph. */ if (list!=NULL) { (*list)=insert_in_norm_info_list(output,node,(*list)); } else { node->outputs=sorted_insert(output,node->outputs); } } Transition* trans=state->transitions; unichar tmp[1024]; while (trans!=NULL) { if (trans->tag_number<0) { /* Case of a subgraph call */ struct norm_info* tmp_list=NULL; explore_normalization_fst2(fst2,fst2->initial_states[-(trans->tag_number)],node, tokens,output,alph,&tmp_list); while (tmp_list!=NULL) { /* We continue to explore the current graph */ explore_normalization_fst2(fst2,trans->state_number,tmp_list->node, tokens,tmp_list->output,alph,list); struct norm_info* z=tmp_list; tmp_list=tmp_list->next; free_norm_info(z); } } else { /* If we have a normal transition */ Fst2Tag tag=fst2->tags[trans->tag_number]; u_strcpy(tmp,output); u_strcat(tmp," "); if (tag->output!=NULL && tag->output[0]!='\0' && u_strcmp(tag->output,"<E>") && !only_spaces(tag->output)) { /* We append the output if it exists and is not epsilon */ u_strcat(tmp,tag->output); } if (!u_strcmp(tag->input,"<E>")) { /* If we have an epsilon transition, we go on in the fst2, but * we don't move in the normalization tree */ explore_normalization_fst2(fst2,trans->state_number,node,tokens,tmp,alph,list); } else { /* If we have a normal transition, we explore all the tokens that match it */ struct list_int* l=get_token_list_for_sequence(tag->input,alph,tokens); while (l!=NULL) { /* Then, we add a branch in the normalization tree for * each token. Note that it may introduce combinatory explosions * if the the fst2 matches large sequences */ struct normalization_tree_transition* trans_norm; trans_norm=get_transition(l->n,node->trans); if (trans_norm==NULL) { /* If the transition does not exist in the tree, we create it */ trans_norm=new_normalization_tree_transition(l->n,new_normalization_tree(),node->trans); node->trans=trans_norm; } explore_normalization_fst2(fst2,trans->state_number,trans_norm->node, tokens,tmp,alph,list); struct list_int* L=l; l=l->next; free(L); } } } trans=trans->next; } }
/** * This function looks for a transition tagged with the given token number. */ struct normalization_tree_transition* get_transition(int token,struct normalization_tree_transition* t) { if (t==NULL) return NULL; if (t->token==token) return t; return get_transition(token,t->next); }
/** * Returns the index value associated to the given key in the given string_hash. * 'pos' is the current position the key and 'node' is the current node in the * string_hash_tree. If 'insert_if_needed' is non null, the key will be added * in the string_hash if not already present. Otherwise, the function will * return NO_VALUE_INDEX if the key is not in the string_hash. */ int get_value_index_(const unichar* key,int pos,struct string_hash_tree_node* node, struct string_hash* hash,int insert_policy,const unichar* value) { for (;;) { if (node==NULL) { fatal_error("NULL error in get_value_index\n"); } if (key[pos]=='\0') { /* If we are at the end of the key */ if (insert_policy==DONT_INSERT) { /* If we just consult the string_hash with no insert, we just * have to return the value_index of the node */ return node->value_index; } if (node->value_index!=NO_VALUE_INDEX) { /* If the key already exists, we return its value index */ return node->value_index; } /* Here, we have to build a new value index */ if (hash->capacity==DONT_USE_VALUES) { /* If don't uses the 'value' array, there is no limitation */ node->value_index=hash->size; (hash->size)++; } else { /* Otherwise: if there is a maximum capacity */ if (hash->size==hash->capacity) { /* We check if we have reached the end of the 'value' array */ if (hash->bound_policy==DONT_ENLARGE) { /* If we can't enlarge the 'value' array, we fail */ fatal_error("Too much elements in a non extensible array in get_value_index\n"); } /* If we can enlarge the 'value' array, we do it, doubling its capacity */ hash->capacity=2*hash->capacity; hash->value=(unichar**)realloc(hash->value,sizeof(unichar*)*hash->capacity); if (hash->value==NULL) { fatal_alloc_error("get_value_index"); } } node->value_index=hash->size; (hash->size)++; /* u_strdup is supposed to return NULL if 'value' is NULL */ hash->value[node->value_index]=u_strdup(value); } return node->value_index; } /* If we are not at the end of the key, we look for the transition to follow */ struct string_hash_tree_transition* t=get_transition(key[pos],node->trans); if (t==NULL) { /* If there is no suitable transition */ if (insert_policy==DONT_INSERT) { /* If we just look, then we say that we have not found the key */ return NO_VALUE_INDEX; } /* Otherwise, we create a transition */ t=new_string_hash_tree_transition(hash); t->letter=key[pos]; t->next=node->trans; t->node=new_string_hash_tree_node(hash); node->trans=t; } pos++; node=t->node; } }