Ejemplo n.º 1
0
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");
	}
Ejemplo n.º 2
0
 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);
       });
 }
Ejemplo n.º 3
0
 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;
     }
 }
Ejemplo n.º 4
0
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);
	}
}
Ejemplo n.º 6
0
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);
}
Ejemplo n.º 7
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;
}