void Snake::move(const SteerDirection& dir) { if (!_is_alive) return; switch (dir) { case Left: _rotation_angle += _radians_per_move; _move_vector = Matrix(MatrixOp::rotateZ, _rotation_angle) * _translation_vector; break; case Right: _rotation_angle -= _radians_per_move; _move_vector = Matrix(MatrixOp::rotateZ, _rotation_angle) * _translation_vector; break; case Forward: // do nothing break; } if (_move_vector.is_zero()) return; const auto newPoint = _points[_head].topMiddle() + _move_vector; if (_time_to_grow.tick()) { if (is_growing()) _remaining_growth--; else { before_tail_remove(); -- _tail; } const int rem_head = _head; -- _head; _points[_head].assign(newPoint, &_points[_previous_head]); on_head_added(); ASSERT(rem_head != _previous_head); _previous_head = rem_head; } else _points[_head].assign(newPoint, &_points[_previous_head]); }
void ipc_space_terminate( ipc_space_t space) { ipc_entry_t table; ipc_entry_num_t size; mach_port_index_t index; assert(space != IS_NULL); is_write_lock(space); if (!is_active(space)) { is_write_unlock(space); return; } is_mark_inactive(space); /* * If somebody is trying to grow the table, * we must wait until they finish and figure * out the space died. */ while (is_growing(space)) is_write_sleep(space); is_write_unlock(space); /* * Now we can futz with it unlocked. */ table = space->is_table; size = space->is_table_size; for (index = 0; index < size; index++) { ipc_entry_t entry = &table[index]; mach_port_type_t type; type = IE_BITS_TYPE(entry->ie_bits); if (type != MACH_PORT_TYPE_NONE) { mach_port_name_t name; name = MACH_PORT_MAKE(index, IE_BITS_GEN(entry->ie_bits)); ipc_right_terminate(space, name, entry); } } it_entries_free(space->is_table_next-1, table); space->is_table_size = 0; /* * Because the space is now dead, * we must release the "active" reference for it. * Our caller still has his reference. */ is_release(space); }
/* * ipc_space_clean - remove all port references from an ipc space. * * In order to follow the traditional semantic, ipc_space_destroy * will not destroy the entire port table of a shared space. Instead * it will simply clear its own sub-space. */ void ipc_space_clean( ipc_space_t space) { ipc_entry_t table; ipc_entry_num_t size; mach_port_index_t index; /* * If somebody is trying to grow the table, * we must wait until they finish and figure * out the space died. */ retry: is_write_lock(space); while (is_growing(space)) is_write_sleep(space); if (!is_active(space)) { is_write_unlock(space); return; } /* * Now we can futz with it since we have the write lock. */ table = space->is_table; size = space->is_table_size; for (index = 0; index < size; index++) { ipc_entry_t entry = &table[index]; mach_port_type_t type; type = IE_BITS_TYPE(entry->ie_bits); if (type != MACH_PORT_TYPE_NONE) { mach_port_name_t name = MACH_PORT_MAKE(index, IE_BITS_GEN(entry->ie_bits)); ipc_right_destroy(space, name, entry, FALSE, 0); /* unlocks space */ goto retry; } } /* * JMM - Now the table is cleaned out. We don't bother shrinking the * size of the table at this point, but we probably should if it is * really large. */ is_write_unlock(space); }