int main(int argc, char** argv) { ensure_eq(argc,2); recordInit(); init_timeop(); ssize_t amt; realpath(argv[0],lackey); char* lastslash = strrchr(lackey,'/'); if(lastslash == NULL) { realpath("./lackey-bin",lackey); } else { // take the real path of us, and convert the end to lackey-bin amt = lastslash - lackey + 1; record(INFO,"realp %s",lackey+amt); memcpy(lackey+amt,"lackey-bin",sizeof("lackey-bin")); } record(INFO, "lackey '%s'",lackey); ensure_eq(0,chdir(argv[1])); // ehhhh dolock(); mkfifo("incoming",0644); // not a directory anymore // we're opening our pipe for writing, so that it doesn't go into an EOF spin loop // when there are no more writers int incoming = open("incoming",O_RDWR|O_NONBLOCK); /* block the signals we care about this does NOT ignore them, but queues them up and interrupts stuff like ppoll (which reenables getting hit by those signals atomically) then we can read info off the signalfd at our leisure, with no signal handler jammed in-between an if(numworkers == 0) and start_worker(); */ waiter_setup(); assert(0 == numworkers); pfd = malloc(sizeof(*pfd)*2); pfd[INCOMING].fd = incoming; pfd[INCOMING].events = POLLIN; pfd[ACCEPTING].fd = start_working(true); pfd[ACCEPTING].events = POLLIN; void clear_incoming(void) { char buf[512]; for(;;) { ssize_t amt = read(incoming,buf,512); if(amt <= 0) { ensure_eq(errno,EAGAIN); break; } } record(INFO,"Incoming fifo unclogged"); }
void object::test<test_id_eq>() { ensure_eq("Eq int", 1, 1); ensure_eq("Eq str", str("a"), "a"); ensure_throws<failure> ("ensure_eq should fail here", []() { ensure_eq("Eq int", 1, 2); }); }
virtual void run_impl() override { bool expect_failure = expected.kind() == jsonv::kind::string && expected.as_string() == "FAILURE"; try { TMergeRules rules; jsonv::value result = jsonv::merge_explicit(rules, jsonv::path(), a, b); ensure(!expect_failure); ensure_eq(expected, result); } catch (...) { if (!expect_failure) throw; } }
bool send_message(size_t which, const struct message m) { record(INFO,"Sending %d to %d",m.id,which); ssize_t amt = write(PFD(which).fd, &m, sizeof(m)); if(amt == 0) { return false; } if(amt < 0) { switch(errno) { case EPIPE: case EBADF: return false; }; perror("write"); abort(); } ensure_eq(amt, sizeof(m)); workers[which].current = m.id; // eh return true; }
void load_test_scene_recoil_players(recoil_players_pool& all_definitions) { using test_id_type = test_scene_recoil_id; all_definitions.reserve(enum_count(test_id_type())); { recoil_player recoil; recoil.offsets = { 0.43297708034515381, 0.9932628870010376, -0.45482802391052246, -0.072165310382843018, 0.60215318202972412, 0.33908355236053467, 0.40217757225036621, -0.84138309955596924, -0.61532247066497803, -0.70864325761795044, -0.57748019695281982, 0.23223221302032471, 0.54007184505462646, 0.047597408294677734, 0.60266327857971191, 0.69486057758331299, -0.42628997564315796, 0.94623100757598877, -0.96650326251983643, 0.47090291976928711 }; const auto test_id = test_scene_recoil_id::GENERIC; recoil.name = format_enum(test_id); const auto id = to_recoil_id(test_id); const auto new_allocation = all_definitions.allocate(std::move(recoil)); (void)id; (void)new_allocation; ensure_eq(new_allocation.key, id); } }
void light_system::render_all_lights(augs::renderer& output, const std::array<float, 16> projection_matrix, const viewing_step step, std::function<void()> neon_callback) { const auto& cosmos = step.cosm; const auto dt = step.get_delta(); const float global_time_seconds = static_cast<float>(step.get_interpolated_total_time_passed_in_seconds()); ensure_eq(0, output.get_triangle_count()); output.light_fbo.use(); glClearColor(0.1f, 0.2f, 0.2f, 1.0f); output.clear_current_fbo(); glClearColor(0.f, 0.f, 0.f, 0.f); auto& light_program = *get_resource_manager().find(assets::program_id::LIGHT); auto& default_program = *get_resource_manager().find(assets::program_id::DEFAULT); light_program.use(); const auto light_pos_uniform = glGetUniformLocation(light_program.id, "light_pos"); const auto light_max_distance_uniform = glGetUniformLocation(light_program.id, "max_distance"); const auto light_attenuation_uniform = glGetUniformLocation(light_program.id, "light_attenuation"); const auto light_multiply_color_uniform = glGetUniformLocation(light_program.id, "multiply_color"); const auto projection_matrix_uniform = glGetUniformLocation(light_program.id, "projection_matrix"); const auto& interp = step.session.systems_audiovisual.get<interpolation_system>(); const auto& particles = step.session.systems_audiovisual.get<particles_simulation_system>(); const auto& visible_per_layer = step.visible.per_layer; std::vector<messages::visibility_information_request> requests; std::vector<messages::visibility_information_response> responses; glUniformMatrix4fv(projection_matrix_uniform, 1, GL_FALSE, projection_matrix.data()); for (const auto it : cosmos.get(processing_subjects::WITH_LIGHT)) { messages::visibility_information_request request; request.eye_transform = it.viewing_transform(interp); request.filter = filters::line_of_sight_query(); request.square_side = it.get<components::light>().max_distance.base_value; request.subject = it; requests.push_back(request); } { std::vector<messages::line_of_sight_response> dummy; visibility_system().respond_to_visibility_information_requests(cosmos, {}, requests, dummy, responses); } const auto camera_transform = step.camera.transform; const auto camera_size = step.camera.visible_world_area; const auto camera_offset = -camera_transform.pos + camera_size / 2; glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE, GL_ONE, GL_ONE); glerr; for (size_t i = 0; i < responses.size(); ++i) { const auto& r = responses[i]; const auto& light_entity = cosmos[requests[i].subject]; const auto& light = light_entity.get<components::light>(); auto& cache = per_entity_cache[light_entity.get_id().pool.indirection_index]; const float delta = dt.in_seconds(); light.constant.variation.update_value(rng, cache.all_variation_values[0], delta); light.linear.variation.update_value(rng, cache.all_variation_values[1], delta); light.quadratic.variation.update_value(rng, cache.all_variation_values[2], delta); light.wall_constant.variation.update_value(rng, cache.all_variation_values[3], delta); light.wall_linear.variation.update_value(rng, cache.all_variation_values[4], delta); light.wall_quadratic.variation.update_value(rng, cache.all_variation_values[5], delta); light.position_variations[0].update_value(rng, cache.all_variation_values[6], delta); light.position_variations[1].update_value(rng, cache.all_variation_values[7], delta); for (size_t t = 0; t < r.get_num_triangles(); ++t) { const auto world_light_tri = r.get_world_triangle(t, requests[i].eye_transform.pos); augs::vertex_triangle renderable_light_tri; renderable_light_tri.vertices[0].pos = world_light_tri.points[0] + camera_offset; renderable_light_tri.vertices[1].pos = world_light_tri.points[1] + camera_offset; renderable_light_tri.vertices[2].pos = world_light_tri.points[2] + camera_offset; auto considered_color = light.color; if (considered_color == black) { considered_color.set_hsv({ fmod(global_time_seconds / 16.f, 1.f), 1.0, 1.0 }); } renderable_light_tri.vertices[0].color = considered_color; renderable_light_tri.vertices[1].color = considered_color; renderable_light_tri.vertices[2].color = considered_color; output.push_triangle(renderable_light_tri); } //for (size_t d = 0; d < r.get_num_discontinuities(); ++d) { // const auto world_discontinuity = *r.get_discontinuity(d); // // if (!world_discontinuity.is_boundary) { // vertex_triangle renderable_light_tri; // // const float distance_from_light = (requests[i].eye_transform.pos - world_discontinuity.points.first).length(); // const float angle = 80.f / ((distance_from_light+0.1f)/50.f); // // //(requests[i].eye_transform.pos - world_discontinuity.points.first).length(); // // if (world_discontinuity.winding == world_discontinuity.RIGHT) { // renderable_light_tri.vertices[0].pos = world_discontinuity.points.first + camera_offset; // renderable_light_tri.vertices[1].pos = world_discontinuity.points.second + camera_offset; // renderable_light_tri.vertices[2].pos = vec2(world_discontinuity.points.second).rotate(-angle, world_discontinuity.points.first) + camera_offset; // } // else { // renderable_light_tri.vertices[0].pos = world_discontinuity.points.first + camera_offset; // renderable_light_tri.vertices[1].pos = world_discontinuity.points.second + camera_offset; // renderable_light_tri.vertices[2].pos = vec2(world_discontinuity.points.second).rotate(angle, world_discontinuity.points.first) + camera_offset; // } // // renderable_light_tri.vertices[0].color = light.color; // renderable_light_tri.vertices[1].color = light.color; // renderable_light_tri.vertices[2].color = light.color; // // output.push_triangle(renderable_light_tri); // } //} vec2 light_displacement = vec2(cache.all_variation_values[6], cache.all_variation_values[7]); auto screen_pos = requests[i].eye_transform - camera_transform; screen_pos.pos.x += camera_size.x * 0.5f; screen_pos.pos.y = camera_size.y - (screen_pos.pos.y + camera_size.y * 0.5f); screen_pos += light_displacement; glUniform2f(light_pos_uniform, screen_pos.pos.x, screen_pos.pos.y); glUniform1f(light_max_distance_uniform, light.max_distance.base_value); glUniform3f(light_attenuation_uniform, cache.all_variation_values[0] + light.constant.base_value, cache.all_variation_values[1] + light.linear.base_value, cache.all_variation_values[2] + light.quadratic.base_value ); glUniform3f(light_multiply_color_uniform, 1.f, 1.f, 1.f); output.call_triangles(); output.clear_triangles(); light_program.use(); glUniform1f(light_max_distance_uniform, light.wall_max_distance.base_value); glUniform3f(light_attenuation_uniform, cache.all_variation_values[3] + light.wall_constant.base_value, cache.all_variation_values[4] + light.wall_linear.base_value, cache.all_variation_values[5] + light.wall_quadratic.base_value ); glUniform3f(light_multiply_color_uniform, light.color.r/255.f, light.color.g/255.f, light.color.b/255.f); render_system().draw_entities(interp, global_time_seconds,output.triangles, visible_per_layer[render_layer::DYNAMIC_BODY], step.camera, renderable_drawing_type::NORMAL); output.call_triangles(); output.clear_triangles(); glUniform3f(light_multiply_color_uniform, 1.f, 1.f, 1.f); } default_program.use(); render_system().draw_entities(interp, global_time_seconds,output.triangles, visible_per_layer[render_layer::DYNAMIC_BODY], step.camera, renderable_drawing_type::NEON_MAPS); render_system().draw_entities(interp, global_time_seconds,output.triangles, visible_per_layer[render_layer::SMALL_DYNAMIC_BODY], step.camera, renderable_drawing_type::NEON_MAPS); render_system().draw_entities(interp, global_time_seconds,output.triangles, visible_per_layer[render_layer::FLYING_BULLETS], step.camera, renderable_drawing_type::NEON_MAPS); render_system().draw_entities(interp, global_time_seconds,output.triangles, visible_per_layer[render_layer::CAR_INTERIOR], step.camera, renderable_drawing_type::NEON_MAPS); render_system().draw_entities(interp, global_time_seconds,output.triangles, visible_per_layer[render_layer::CAR_WHEEL], step.camera, renderable_drawing_type::NEON_MAPS); render_system().draw_entities(interp, global_time_seconds,output.triangles, visible_per_layer[render_layer::EFFECTS], step.camera, renderable_drawing_type::NEON_MAPS); render_system().draw_entities(interp, global_time_seconds,output.triangles, visible_per_layer[render_layer::ON_GROUND], step.camera, renderable_drawing_type::NEON_MAPS); render_system().draw_entities(interp, global_time_seconds,output.triangles, visible_per_layer[render_layer::ON_TILED_FLOOR], step.camera, renderable_drawing_type::NEON_MAPS); { particles_simulation_system::drawing_input in(output.triangles); in.camera = step.camera; in.drawing_type = renderable_drawing_type::NEON_MAPS; particles.draw(render_layer::EFFECTS, in); } neon_callback(); output.call_triangles(); output.clear_triangles(); glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE); glerr; augs::graphics::fbo::use_default(); output.set_active_texture(2); output.bind_texture(output.light_fbo); output.set_active_texture(0); }
physics_system& physics_system::operator=(const physics_system& b) { ray_casts_since_last_step = b.ray_casts_since_last_step; accumulated_messages = b.accumulated_messages; b2World& b2 = *b2world.get(); b2.~b2World(); new (&b2) b2World(b2Vec2(0.f, 0.f)); const b2World& b2c = *b.b2world.get(); // do the initial trivial copy b2 = b2c; // no need to install a new allocator since its operator= is a non-op // new (&b2.m_blockAllocator) b2BlockAllocator; // reset the allocator pointer to the new one b2.m_contactManager.m_allocator = &b2.m_blockAllocator; std::unordered_map<void*, void*> pointer_migrations; std::unordered_map<void*, size_t> m_nodeAB_offset; b2BlockAllocator& migrated_allocator = b2.m_blockAllocator; #if PROTECT_MIGRATIONS std::unordered_set<void**> already_migrated; auto old_allocations = migrated_allocator.allocations; migrated_allocator.allocations.clear(); #endif auto migrate_pointer = [ #if PROTECT_MIGRATIONS &already_migrated, &old_allocations, #endif &pointer_migrations, &migrated_allocator](auto*& ptr, const unsigned num = 1) { #if PROTECT_MIGRATIONS ensure(already_migrated.find((void**)&ptr) == already_migrated.end()); already_migrated.insert((void**)&ptr); #endif typedef std::remove_pointer<std::decay_t<decltype(ptr)>>::type type; if (ptr == nullptr) { return; } void* const p = reinterpret_cast<void*>(ptr); void* mig_p = nullptr; const size_t s = sizeof(type) * num; auto maybe_migrated = pointer_migrations.find(p); if (maybe_migrated == pointer_migrations.end()) { mig_p = migrated_allocator.Allocate(s); memcpy(mig_p, p, s); pointer_migrations.insert(std::make_pair(p, mig_p)); #if PROTECT_MIGRATIONS if(old_allocations.find(p) != old_allocations.end()) old_allocations.erase(p); #endif } else { mig_p = (*maybe_migrated).second; } ptr = reinterpret_cast<type*>(mig_p); }; auto migrate_edge = [ #if PROTECT_MIGRATIONS &already_migrated, #endif &pointer_migrations, &m_nodeAB_offset](b2ContactEdge*& ptr) { #if PROTECT_MIGRATIONS ensure(already_migrated.find((void**)&ptr) == already_migrated.end()); already_migrated.insert((void**)&ptr); #endif if (ptr == nullptr) { return; } else { const size_t off = m_nodeAB_offset.at(ptr); ensure(off == offsetof(b2Contact, m_nodeA) || off == offsetof(b2Contact, m_nodeB)); char* owner_contact = (char*)ptr - off; // here "at" requires that the contacts be already migrated char* remapped_contact = (char*)pointer_migrations.at(owner_contact); ptr = (b2ContactEdge*)(remapped_contact + off); } }; // migrate proxy tree userdatas auto& proxy_tree = b2.m_contactManager.m_broadPhase.m_tree; //for (size_t i = 0; i < proxy_tree.m_nodeCount; ++i) { // migrate_pointer(proxy_tree.m_nodes[i].userData); //} // acquire contact edge offsets for (b2Contact* c = b2.m_contactManager.m_contactList; c; c = c->m_next) { m_nodeAB_offset.insert(std::make_pair(&c->m_nodeA, offsetof(b2Contact, m_nodeA))); m_nodeAB_offset.insert(std::make_pair(&c->m_nodeB, offsetof(b2Contact, m_nodeB))); } // migrate contact pointers migrate_pointer(b2.m_contactManager.m_contactList); for (b2Contact* c = b2.m_contactManager.m_contactList; c; c = c->m_next) { migrate_pointer(c->m_prev); migrate_pointer(c->m_next); migrate_pointer(c->m_fixtureA); migrate_pointer(c->m_fixtureB); c->m_nodeA.contact = c; migrate_pointer(c->m_nodeA.other); c->m_nodeB.contact = c; migrate_pointer(c->m_nodeB.other); } // migrate contact edges of contacts for (b2Contact* c = b2.m_contactManager.m_contactList; c; c = c->m_next) { migrate_edge(c->m_nodeA.next); migrate_edge(c->m_nodeA.prev); migrate_edge(c->m_nodeB.next); migrate_edge(c->m_nodeB.prev); } // migrate bodies and fixtures migrate_pointer(b2.m_bodyList); for (b2Body* b = b2.m_bodyList; b; b = b->m_next) { //auto rigid_body_cache_id = b->m_userData.pool.indirection_index; //rigid_body_caches[rigid_body_cache_id].body = b; migrate_pointer(b->m_fixtureList); migrate_pointer(b->m_prev); migrate_pointer(b->m_next); migrate_pointer(b->m_jointList); migrate_pointer(b->m_ownerFrictionGround); migrate_edge(b->m_contactList); b->m_world = &b2; for (b2Fixture* f = b->m_fixtureList; f; f = f->m_next) { f->m_body = b; migrate_pointer(f->m_proxies, f->m_proxyCount); f->m_shape = f->m_shape->Clone(&migrated_allocator); migrate_pointer(f->m_next); for (size_t i = 0; i < f->m_proxyCount; ++i) { f->m_proxies[i].fixture = f; void*& ud = proxy_tree.m_nodes[f->m_proxies[i].proxyId].userData; ud = pointer_migrations.at(ud); } //auto c_idx = f->collider_index; //auto& cache = colliders_caches[f->m_userData.pool.indirection_index]; //cache.correspondent_rigid_body_cache = rigid_body_cache_id; // //if (c_idx >= cache.fixtures_per_collider.size()) { // ensure_eq(c_idx, cache.fixtures_per_collider.size()); // cache.fixtures_per_collider.push_back(std::vector<b2Fixture*>()); //} // //cache.fixtures_per_collider[c_idx].push_back(f); } } colliders_caches = b.colliders_caches; rigid_body_caches = b.rigid_body_caches; for (auto& c : colliders_caches) { for (auto& fv : c.fixtures_per_collider) { for (auto& f : fv) { f = reinterpret_cast<b2Fixture*>(pointer_migrations.at(reinterpret_cast<void*>(f))); } } } for (auto& c : rigid_body_caches) { if (c.body) { c.body = reinterpret_cast<b2Body*>(pointer_migrations.at(reinterpret_cast<void*>(c.body))); } } // ensure that all allocations have been migrated #if PROTECT_MIGRATIONS ensure(old_allocations.empty()); ensure_eq(b2c.m_blockAllocator.allocations.size(), migrated_allocator.allocations.size()); #endif return *this; }