bool is_entity(ast_t* type, token_id entity) { if(type == NULL) return false; switch(ast_id(type)) { case TK_TUPLETYPE: return false; case TK_UNIONTYPE: { ast_t* child = ast_child(type); while(child != NULL) { if(!is_entity(child, entity)) return false; child = ast_sibling(child); } return true; } case TK_ISECTTYPE: { ast_t* child = ast_child(type); while(child != NULL) { if(is_entity(child, entity)) return true; child = ast_sibling(child); } return false; } case TK_NOMINAL: { ast_t* def = (ast_t*)ast_data(type); return ast_id(def) == entity; } case TK_ARROW: return is_entity(ast_childidx(type, 1), entity); case TK_TYPEPARAMREF: return is_entity(typeparam_constraint(type), entity); default: {} } assert(0); return false; }
/** * @brief Registers a timer into a context (table or a userdata). * @param timer A timer. * @param context_index Index of the table or userdata in the stack. * @param callback_index Index of the function to call when the timer finishes. */ void LuaContext::add_timer(Timer* timer, int context_index, int callback_index) { const void* context; if (lua_type(l, context_index) == LUA_TUSERDATA) { ExportableToLua** userdata = static_cast<ExportableToLua**>( lua_touserdata(l, context_index)); context = *userdata; } else { context = lua_topointer(l, context_index); } lua_pushvalue(l, callback_index); int callback_ref = create_ref(); timers[timer].callback_ref = callback_ref; timers[timer].context = context; Game* game = main_loop.get_game(); if (game != NULL) { // We are during a game: depending on the timer's context, // when the map is suspended, also suspend the timer or not. if (is_map(l, context_index) || is_entity(l, context_index) || is_item(l, context_index)) { timer->set_suspended_with_map(true); } } timer->increment_refcount(); }
void set_entity_owner(ir_entity *ent, ir_type *owner) { assert(is_entity(ent)); assert(is_compound_type(owner)); remove_compound_member(ent->owner, ent); add_compound_member(owner, ent); ent->owner = owner; }
/** * @brief Registers a timer into a context (table or a userdata). * @param timer A timer. * @param context_index Index of the table or userdata in the stack. * @param callback_index Index of the function to call when the timer finishes. */ void LuaContext::add_timer(Timer* timer, int context_index, int callback_index) { const void* context; if (lua_type(l, context_index) == LUA_TUSERDATA) { ExportableToLua** userdata = static_cast<ExportableToLua**>( lua_touserdata(l, context_index)); context = *userdata; } else { context = lua_topointer(l, context_index); } lua_pushvalue(l, callback_index); int callback_ref = create_ref(); #ifndef NDEBUG // Sanity check: check the uniqueness of the ref. std::map<Timer*, LuaTimerData>::iterator it; for (it = timers.begin(); it != timers.end(); ++it) { if (it->second.callback_ref == callback_ref) { Debug::die(StringConcat() << "Callback ref " << callback_ref << " is already used by a timer (duplicate luaL_unref?)"); } } #endif Debug::check_assertion(timers.find(timer) == timers.end(), "Duplicate timer in the system"); timers[timer].callback_ref = callback_ref; timers[timer].context = context; Game* game = main_loop.get_game(); if (game != NULL) { // We are during a game: depending on the timer's context, // suspend the timer or not. if (is_map(l, context_index) || is_entity(l, context_index) || is_item(l, context_index)) { // By default, we want the timer to be automatically suspended when a // camera movement, a dialog or the pause menu starts. timer->set_suspended_with_map(true); // But in the initial state, we override that rule. // We initially suspend the timer only during a dialog. // In particular, we don't want to suspend timers created during a // camera movement. // This would be very painful for users. bool initially_suspended = game->is_dialog_enabled(); timer->set_suspended(initially_suspended); } } timer->increment_refcount(); }
static void check_tore(type_or_ent tore, void *env) { bool *fine = (bool*)env; if (is_type(tore.typ)) { *fine &= check_type(tore.typ); } else { assert(is_entity(tore.ent)); *fine &= check_entity(tore.ent); } }
ir_entity *copy_entity_own(ir_entity *old, ir_type *new_owner) { assert(is_entity(old)); assert(is_compound_type(new_owner)); assert(get_type_state(new_owner) != layout_fixed); if (old->owner == new_owner) return old; /* create a deep copy so we are safe of aliasing and double-freeing. */ ir_entity *newe = deep_entity_copy(old); newe->owner = new_owner; add_compound_member(new_owner, newe); return newe; }
/** * Pre-Walker: Copies blocks and nodes from the original method graph * to the copied graph. * * @param n A node from the original method graph. * @param env The copied graph. */ static void copy_all_nodes(ir_node *node, void *env) { ir_graph *irg = (ir_graph*)env; ir_node *new_node = irn_copy_into_irg(node, irg); set_irn_link(node, new_node); /* fix access to entities on the stack frame */ if (is_Member(new_node)) { ir_entity *ent = get_Member_entity(new_node); ir_type *tp = get_entity_owner(ent); if (is_frame_type(tp)) { /* replace by the copied entity */ ent = (ir_entity*)get_entity_link(ent); assert(is_entity(ent)); assert(get_entity_owner(ent) == get_irg_frame_type(irg)); set_Member_entity(new_node, ent); } } }
/** * \brief Registers a timer into a context (table or a userdata). * \param timer A timer. * \param context_index Index of the table or userdata in the stack. * \param callback_ref Lua ref to the function to call when the timer finishes. */ void LuaContext::add_timer( const TimerPtr& timer, int context_index, const ScopedLuaRef& callback_ref ) { const void* context; if (lua_type(l, context_index) == LUA_TUSERDATA) { ExportableToLuaPtr* userdata = static_cast<ExportableToLuaPtr*>( lua_touserdata(l, context_index) ); context = userdata->get(); } else { context = lua_topointer(l, context_index); } callback_ref.push(); #ifndef NDEBUG // Sanity check: check the uniqueness of the ref. for (const auto& kvp: timers) { if (kvp.second.callback_ref.get() == callback_ref.get()) { std::ostringstream oss; oss << "Callback ref " << callback_ref.get() << " is already used by a timer (duplicate luaL_unref?)"; Debug::die(oss.str()); } } #endif Debug::check_assertion(timers.find(timer) == timers.end(), "Duplicate timer in the system"); timers[timer].callback_ref = callback_ref; timers[timer].context = context; Game* game = main_loop.get_game(); if (game != nullptr) { // We are during a game: depending on the timer's context, // suspend the timer or not. if (is_map(l, context_index) || is_entity(l, context_index) || is_item(l, context_index)) { bool initially_suspended = false; // By default, we want the timer to be automatically suspended when a // camera movement, a dialog or the pause menu starts. if (!is_entity(l, context_index)) { // The timer normally gets suspended/resumed with the map. timer->set_suspended_with_map(true); // But in the initial state, we override that rule. // We initially suspend the timer only during a dialog. // In particular, we don't want to suspend timers created during a // camera movement. // This would be very painful for users. initially_suspended = game->is_dialog_enabled(); } else { // Entities are more complex: they also get suspended when disabled // and when far from the camera. Therefore, they don't simply follow // the map suspended state. EntityPtr entity = check_entity(l, context_index); initially_suspended = entity->is_suspended() || !entity->is_enabled(); } timer->set_suspended(initially_suspended); } } }
/** * \brief Registers a timer into a context (table or a userdata). * \param timer A timer. * \param context_index Index of the table or userdata in the stack. * \param callback_index Index of the function to call when the timer finishes. */ void LuaContext::add_timer(Timer* timer, int context_index, int callback_index) { const void* context; if (lua_type(l, context_index) == LUA_TUSERDATA) { ExportableToLua** userdata = static_cast<ExportableToLua**>( lua_touserdata(l, context_index)); context = *userdata; } else { context = lua_topointer(l, context_index); } lua_pushvalue(l, callback_index); int callback_ref = create_ref(); #ifndef NDEBUG // Sanity check: check the uniqueness of the ref. std::map<Timer*, LuaTimerData>::iterator it; for (it = timers.begin(); it != timers.end(); ++it) { if (it->second.callback_ref == callback_ref) { std::ostringstream oss; oss << "Callback ref " << callback_ref << " is already used by a timer (duplicate luaL_unref?)"; Debug::die(oss.str()); } } #endif Debug::check_assertion(timers.find(timer) == timers.end(), "Duplicate timer in the system"); timers[timer].callback_ref = callback_ref; timers[timer].context = context; Game* game = main_loop.get_game(); if (game != NULL) { // We are during a game: depending on the timer's context, // suspend the timer or not. if (is_map(l, context_index) || is_entity(l, context_index) || is_item(l, context_index)) { bool initially_suspended = false; // By default, we want the timer to be automatically suspended when a // camera movement, a dialog or the pause menu starts. if (!is_entity(l, context_index)) { // The timer normally get suspended/unsuspend with the map. timer->set_suspended_with_map(true); // But in the initial state, we override that rule. // We initially suspend the timer only during a dialog. // In particular, we don't want to suspend timers created during a // camera movement. // This would be very painful for users. initially_suspended = game->is_dialog_enabled(); } else { // Entities are more complex: they also get suspended when disabled // and when far from the camera. Therefore, they don't simply follow // the map suspended state. const MapEntity& entity = check_entity(l, context_index); initially_suspended = entity.is_suspended() || !entity.is_enabled(); } timer->set_suspended(initially_suspended); } } RefCountable::ref(timer); }
DomEntity DomNode::to_entity() const { if (is_entity()) return DomEntity(impl); return DomEntity(); }