Пример #1
0
bool GodotSharpBuilds::copy_api_assembly(const String &p_src_dir, const String &p_dst_dir, const String &p_assembly_name) {

	String assembly_file = p_assembly_name + ".dll";
	String assembly_src = p_src_dir.plus_file(assembly_file);
	String assembly_dst = p_dst_dir.plus_file(assembly_file);

	if (!FileAccess::exists(assembly_dst) || FileAccess::get_modified_time(assembly_src) > FileAccess::get_modified_time(assembly_dst)) {
		DirAccess *da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM);

		String xml_file = p_assembly_name + ".xml";
		if (da->copy(p_src_dir.plus_file(xml_file), p_dst_dir.plus_file(xml_file)) != OK)
			WARN_PRINTS("Failed to copy " + xml_file);

		String pdb_file = p_assembly_name + ".pdb";
		if (da->copy(p_src_dir.plus_file(pdb_file), p_dst_dir.plus_file(pdb_file)) != OK)
			WARN_PRINTS("Failed to copy " + pdb_file);

		Error err = da->copy(assembly_src, assembly_dst);

		memdelete(da);

		if (err != OK) {
			show_build_error_dialog("Failed to copy " API_ASSEMBLY_NAME ".dll");
			return false;
		}
	}

	return true;
}
Пример #2
0
void HingeJointBullet::set_param(PhysicsServer::HingeJointParam p_param, real_t p_value) {
	switch (p_param) {
		case PhysicsServer::HINGE_JOINT_BIAS:
			if (0 < p_value) {
				print_line("The Bullet Hinge Joint doesn't support bias, So it's always 0");
			}
			break;
		case PhysicsServer::HINGE_JOINT_LIMIT_UPPER:
			hingeConstraint->setLimit(hingeConstraint->getLowerLimit(), p_value, hingeConstraint->getLimitSoftness(), hingeConstraint->getLimitBiasFactor(), hingeConstraint->getLimitRelaxationFactor());
			break;
		case PhysicsServer::HINGE_JOINT_LIMIT_LOWER:
			hingeConstraint->setLimit(p_value, hingeConstraint->getUpperLimit(), hingeConstraint->getLimitSoftness(), hingeConstraint->getLimitBiasFactor(), hingeConstraint->getLimitRelaxationFactor());
			break;
		case PhysicsServer::HINGE_JOINT_LIMIT_BIAS:
			hingeConstraint->setLimit(hingeConstraint->getLowerLimit(), hingeConstraint->getUpperLimit(), hingeConstraint->getLimitSoftness(), p_value, hingeConstraint->getLimitRelaxationFactor());
			break;
		case PhysicsServer::HINGE_JOINT_LIMIT_SOFTNESS:
			hingeConstraint->setLimit(hingeConstraint->getLowerLimit(), hingeConstraint->getUpperLimit(), p_value, hingeConstraint->getLimitBiasFactor(), hingeConstraint->getLimitRelaxationFactor());
			break;
		case PhysicsServer::HINGE_JOINT_LIMIT_RELAXATION:
			hingeConstraint->setLimit(hingeConstraint->getLowerLimit(), hingeConstraint->getUpperLimit(), hingeConstraint->getLimitSoftness(), hingeConstraint->getLimitBiasFactor(), p_value);
			break;
		case PhysicsServer::HINGE_JOINT_MOTOR_TARGET_VELOCITY:
			hingeConstraint->setMotorTargetVelocity(p_value);
			break;
		case PhysicsServer::HINGE_JOINT_MOTOR_MAX_IMPULSE:
			hingeConstraint->setMaxMotorImpulse(p_value);
			break;
		default:
			WARN_PRINTS("The Bullet Hinge Joint doesn't support this parameter: " + itos(p_param) + ", value: " + itos(p_value));
	}
}
Пример #3
0
void RigidBodyBullet::set_param(PhysicsServer::BodyParameter p_param, real_t p_value) {
	switch (p_param) {
		case PhysicsServer::BODY_PARAM_BOUNCE:
			btBody->setRestitution(p_value);
			break;
		case PhysicsServer::BODY_PARAM_FRICTION:
			btBody->setFriction(p_value);
			break;
		case PhysicsServer::BODY_PARAM_MASS: {
			ERR_FAIL_COND(p_value < 0);
			mass = p_value;
			_internal_set_mass(p_value);
			break;
		}
		case PhysicsServer::BODY_PARAM_LINEAR_DAMP:
			linearDamp = p_value;
			btBody->setDamping(linearDamp, angularDamp);
			break;
		case PhysicsServer::BODY_PARAM_ANGULAR_DAMP:
			angularDamp = p_value;
			btBody->setDamping(linearDamp, angularDamp);
			break;
		case PhysicsServer::BODY_PARAM_GRAVITY_SCALE:
			gravity_scale = p_value;
			/// The Bullet gravity will be is set by reload_space_override_modificator
			scratch_space_override_modificator();
			break;
		default:
			WARN_PRINTS("Parameter " + itos(p_param) + " not supported by bullet. Value: " + itos(p_value));
	}
}
Пример #4
0
void EditorAddonLibrary::_image_request_completed(int p_status, int p_code, const StringArray& headers, const ByteArray& p_data,int p_queue_id) {

	ERR_FAIL_COND( !image_queue.has(p_queue_id) );

	if (p_status==HTTPRequest::RESULT_SUCCESS) {


		print_line("GOT IMAGE YAY!");
		Object *obj = ObjectDB::get_instance(image_queue[p_queue_id].target);

		if (obj) {
			int len=p_data.size();
			ByteArray::Read r=p_data.read();

			Image image(r.ptr(),len);
			if (!image.empty()) {
				Ref<ImageTexture> tex;
				tex.instance();
				tex->create_from_image(image);

				obj->call("set_image",image_queue[p_queue_id].image_type,image_queue[p_queue_id].image_index,tex);
			}
		}
	} else {
		WARN_PRINTS("Error getting PNG file for asset id "+itos(image_queue[p_queue_id].asset_id));
	}

	image_queue[p_queue_id].request->queue_delete();;
	image_queue.erase(p_queue_id);

	_update_image_queue();

}
Пример #5
0
void AreaBullet::set_param(PhysicsServer::AreaParameter p_param, const Variant &p_value) {
	switch (p_param) {
		case PhysicsServer::AREA_PARAM_GRAVITY:
			set_spOv_gravityMag(p_value);
			break;
		case PhysicsServer::AREA_PARAM_GRAVITY_VECTOR:
			set_spOv_gravityVec(p_value);
			break;
		case PhysicsServer::AREA_PARAM_LINEAR_DAMP:
			set_spOv_linearDump(p_value);
			break;
		case PhysicsServer::AREA_PARAM_ANGULAR_DAMP:
			set_spOv_angularDump(p_value);
			break;
		case PhysicsServer::AREA_PARAM_PRIORITY:
			set_spOv_priority(p_value);
			break;
		case PhysicsServer::AREA_PARAM_GRAVITY_IS_POINT:
			set_spOv_gravityPoint(p_value);
			break;
		case PhysicsServer::AREA_PARAM_GRAVITY_DISTANCE_SCALE:
			set_spOv_gravityPointDistanceScale(p_value);
			break;
		case PhysicsServer::AREA_PARAM_GRAVITY_POINT_ATTENUATION:
			set_spOv_gravityPointAttenuation(p_value);
			break;
		default:
			WARN_PRINTS("Area doesn't support this parameter in the Bullet backend: " + itos(p_param));
	}
}
Пример #6
0
void StreamPeerMbedTLS::_load_certs(const PoolByteArray &p_array) {
	int arr_len = p_array.size();
	PoolByteArray::Read r = p_array.read();
	int err = mbedtls_x509_crt_parse(&cacert, &r[0], arr_len);
	if (err != 0) {
		WARN_PRINTS("Error parsing some certificates: " + itos(err));
	}
}
Пример #7
0
int LWSClient::_handle_cb(struct lws *wsi, enum lws_callback_reasons reason, void *user, void *in, size_t len) {

	Ref<LWSPeer> peer = static_cast<Ref<LWSPeer> >(_peer);
	LWSPeer::PeerData *peer_data = (LWSPeer::PeerData *)user;

	switch (reason) {
		case LWS_CALLBACK_OPENSSL_LOAD_EXTRA_CLIENT_VERIFY_CERTS: {
			PoolByteArray arr = StreamPeerSSL::get_project_cert_array();
			if (arr.size() > 0)
				SSL_CTX_add_client_CA((SSL_CTX *)user, d2i_X509(NULL, &arr.read()[0], arr.size()));
			else if (verify_ssl)
				WARN_PRINTS("No CA cert specified in project settings, SSL will not work");
		} break;

		case LWS_CALLBACK_CLIENT_ESTABLISHED:
			peer->set_wsi(wsi);
			peer_data->peer_id = 0;
			peer_data->force_close = false;
			_on_connect(lws_get_protocol(wsi)->name);
			break;

		case LWS_CALLBACK_CLIENT_CONNECTION_ERROR:
			_on_error();
			destroy_context();
			return -1; // we should close the connection (would probably happen anyway)

		case LWS_CALLBACK_CLIENT_CLOSED:
			peer->close();
			destroy_context();
			_on_disconnect();
			return 0; // we can end here

		case LWS_CALLBACK_CLIENT_RECEIVE:
			peer->read_wsi(in, len);
			if (peer->get_available_packet_count() > 0)
				_on_peer_packet();
			break;

		case LWS_CALLBACK_CLIENT_WRITEABLE:
			if (peer_data->force_close)
				return -1;

			peer->write_wsi();
			break;

		default:
			break;
	}

	return 0;
}
Пример #8
0
void AudioEffectRecord::set_recording_active(bool p_record) {
	if (p_record) {
		if (current_instance == 0) {
			WARN_PRINTS("Recording should not be set as active before Godot has initialized.");
			recording_active = false;
			return;
		}

		ensure_thread_stopped();
		current_instance->init();
	}

	recording_active = p_record;
}
Пример #9
0
Variant RigidBodyBullet::get_state(PhysicsServer::BodyState p_state) const {
	switch (p_state) {
		case PhysicsServer::BODY_STATE_TRANSFORM:
			return get_transform();
		case PhysicsServer::BODY_STATE_LINEAR_VELOCITY:
			return get_linear_velocity();
		case PhysicsServer::BODY_STATE_ANGULAR_VELOCITY:
			return get_angular_velocity();
		case PhysicsServer::BODY_STATE_SLEEPING:
			return !is_active();
		case PhysicsServer::BODY_STATE_CAN_SLEEP:
			return can_sleep;
		default:
			WARN_PRINTS("This state " + itos(p_state) + " is not supported by Bullet");
			return Variant();
	}
}
Пример #10
0
real_t RigidBodyBullet::get_param(PhysicsServer::BodyParameter p_param) const {
	switch (p_param) {
		case PhysicsServer::BODY_PARAM_BOUNCE:
			return btBody->getRestitution();
		case PhysicsServer::BODY_PARAM_FRICTION:
			return btBody->getFriction();
		case PhysicsServer::BODY_PARAM_MASS: {
			const btScalar invMass = btBody->getInvMass();
			return 0 == invMass ? 0 : 1 / invMass;
		}
		case PhysicsServer::BODY_PARAM_LINEAR_DAMP:
			return linearDamp;
		case PhysicsServer::BODY_PARAM_ANGULAR_DAMP:
			return angularDamp;
		case PhysicsServer::BODY_PARAM_GRAVITY_SCALE:
			return gravity_scale;
		default:
			WARN_PRINTS("Parameter " + itos(p_param) + " not supported by bullet");
			return 0;
	}
}
Пример #11
0
Error AudioDriverWASAPI::init_render_device(bool reinit) {

	Error err = audio_device_init(&audio_output, false, reinit);
	if (err != OK)
		return err;

	switch (audio_output.channels) {
		case 2: // Stereo
		case 4: // Surround 3.1
		case 6: // Surround 5.1
		case 8: // Surround 7.1
			channels = audio_output.channels;
			break;

		default:
			WARN_PRINTS("WASAPI: Unsupported number of channels: " + itos(audio_output.channels));
			channels = 2;
			break;
	}

	UINT32 max_frames;
	HRESULT hr = audio_output.audio_client->GetBufferSize(&max_frames);
	ERR_FAIL_COND_V(hr != S_OK, ERR_CANT_OPEN);

	// Due to WASAPI Shared Mode we have no control of the buffer size
	buffer_frames = max_frames;

	// Sample rate is independent of channels (ref: https://stackoverflow.com/questions/11048825/audio-sample-frequency-rely-on-channels)
	samples_in.resize(buffer_frames * channels);

	input_position = 0;
	input_size = 0;

	print_verbose("WASAPI: detected " + itos(channels) + " channels");
	print_verbose("WASAPI: audio buffer frames: " + itos(buffer_frames) + " calculated latency: " + itos(buffer_frames * 1000 / mix_rate) + "ms");

	return OK;
}
Пример #12
0
Variant AreaBullet::get_param(PhysicsServer::AreaParameter p_param) const {
	switch (p_param) {
		case PhysicsServer::AREA_PARAM_GRAVITY:
			return spOv_gravityMag;
		case PhysicsServer::AREA_PARAM_GRAVITY_VECTOR:
			return spOv_gravityVec;
		case PhysicsServer::AREA_PARAM_LINEAR_DAMP:
			return spOv_linearDump;
		case PhysicsServer::AREA_PARAM_ANGULAR_DAMP:
			return spOv_angularDump;
		case PhysicsServer::AREA_PARAM_PRIORITY:
			return spOv_priority;
		case PhysicsServer::AREA_PARAM_GRAVITY_IS_POINT:
			return spOv_gravityPoint;
		case PhysicsServer::AREA_PARAM_GRAVITY_DISTANCE_SCALE:
			return spOv_gravityPointDistanceScale;
		case PhysicsServer::AREA_PARAM_GRAVITY_POINT_ATTENUATION:
			return spOv_gravityPointAttenuation;
		default:
			WARN_PRINTS("Area doesn't support this parameter in the Bullet backend: " + itos(p_param));
			return Variant();
	}
}
Пример #13
0
real_t HingeJointBullet::get_param(PhysicsServer::HingeJointParam p_param) const {
	switch (p_param) {
		case PhysicsServer::HINGE_JOINT_BIAS:
			return 0;
			break;
		case PhysicsServer::HINGE_JOINT_LIMIT_UPPER:
			return hingeConstraint->getUpperLimit();
		case PhysicsServer::HINGE_JOINT_LIMIT_LOWER:
			return hingeConstraint->getLowerLimit();
		case PhysicsServer::HINGE_JOINT_LIMIT_BIAS:
			return hingeConstraint->getLimitBiasFactor();
		case PhysicsServer::HINGE_JOINT_LIMIT_SOFTNESS:
			return hingeConstraint->getLimitSoftness();
		case PhysicsServer::HINGE_JOINT_LIMIT_RELAXATION:
			return hingeConstraint->getLimitRelaxationFactor();
		case PhysicsServer::HINGE_JOINT_MOTOR_TARGET_VELOCITY:
			return hingeConstraint->getMotorTargetVelocity();
		case PhysicsServer::HINGE_JOINT_MOTOR_MAX_IMPULSE:
			return hingeConstraint->getMaxMotorImpulse();
		default:
			WARN_PRINTS("The Bullet Hinge Joint doesn't support this parameter: " + itos(p_param));
			return 0;
	}
}
Пример #14
0
void EditorPluginSettings::update_plugins() {


	plugin_list->clear();

	DirAccess *da = DirAccess::create(DirAccess::ACCESS_RESOURCES);
	Error err = da->change_dir("res://addons");
	if (err!=OK) {
		memdelete(da);
		return;
	}

	updating=true;

	TreeItem *root = plugin_list->create_item();

	da->list_dir_begin();

	String d = da->get_next();

	Vector<String> plugins;

	while(d!=String()) {

		bool dir = da->current_is_dir();
		String path = "res://addons/"+d+"/plugin.cfg";

		if (dir && FileAccess::exists(path)) {

			plugins.push_back(d);
		}

		d = da->get_next();
	}

	da->list_dir_end();
	memdelete(da);

	plugins.sort();

	Vector<String> active_plugins = GlobalConfig::get_singleton()->get("plugins/active");

	for(int i=0;i<plugins.size();i++) {

		Ref<ConfigFile> cf;
		cf.instance();
		String path = "res://addons/"+plugins[i]+"/plugin.cfg";

		Error err = cf->load(path);

		if (err!=OK) {
			WARN_PRINTS("Can't load plugin config: "+path);
		} else if (!cf->has_section_key("plugin","name")) {
			WARN_PRINTS("Plugin misses plugin/name: "+path);
		} else if (!cf->has_section_key("plugin","author")) {
			WARN_PRINTS("Plugin misses plugin/author: "+path);
		} else if (!cf->has_section_key("plugin","version")) {
			WARN_PRINTS("Plugin misses plugin/version: "+path);
		} else if (!cf->has_section_key("plugin","description")) {
			WARN_PRINTS("Plugin misses plugin/description: "+path);
		} else if (!cf->has_section_key("plugin","script")) {
			WARN_PRINTS("Plugin misses plugin/script: "+path);
		} else {

			String d = plugins[i];
			String name = cf->get_value("plugin","name");
			String author = cf->get_value("plugin","author");
			String version = cf->get_value("plugin","version");
			String description = cf->get_value("plugin","description");
			String script = cf->get_value("plugin","script");

			TreeItem *item = plugin_list->create_item(root);
			item->set_text(0,name);
			item->set_tooltip(0,"Name: "+name+"\nPath: "+path+"\nMain Script: "+script);
			item->set_metadata(0,d);
			item->set_text(1,version);
			item->set_metadata(1,script);
			item->set_text(2,author);
			item->set_metadata(2,description);
			item->set_cell_mode(3,TreeItem::CELL_MODE_RANGE);
			item->set_range_config(3,0,1,1);
			item->set_text(3,"Inactive,Active");
			item->set_editable(3,true);

			if (EditorNode::get_singleton()->is_addon_plugin_enabled(d)) {
				item->set_custom_color(3,Color(0.2,1,0.2));
				item->set_range(3,1);
			} else {
				item->set_custom_color(3,Color(1,0.2,0.2));
				item->set_range(3,0);
			}
		}

	}

	updating=false;

}
Пример #15
0
Error FileAccessWindows::_open(const String &p_path, int p_mode_flags) {

	path_src = p_path;
	path = fix_path(p_path);
	if (f)
		close();

	const wchar_t *mode_string;

	if (p_mode_flags == READ)
		mode_string = L"rb";
	else if (p_mode_flags == WRITE)
		mode_string = L"wb";
	else if (p_mode_flags == READ_WRITE)
		mode_string = L"rb+";
	else if (p_mode_flags == WRITE_READ)
		mode_string = L"wb+";
	else
		return ERR_INVALID_PARAMETER;

	/* pretty much every implementation that uses fopen as primary
	   backend supports utf8 encoding */

	struct _stat st;
	if (_wstat(path.c_str(), &st) == 0) {

		if (!S_ISREG(st.st_mode))
			return ERR_FILE_CANT_OPEN;
	};

#ifdef TOOLS_ENABLED
	// Windows is case insensitive, but all other platforms are sensitive to it
	// To ease cross-platform development, we issue a warning if users try to access
	// a file using the wrong case (which *works* on Windows, but won't on other
	// platforms).
	if (p_mode_flags == READ) {
		WIN32_FIND_DATAW d = { 0 };
		HANDLE f = FindFirstFileW(path.c_str(), &d);
		if (f) {
			String fname = d.cFileName;
			if (fname != String()) {

				String base_file = path.get_file();
				if (base_file != fname && base_file.findn(fname) == 0) {
					WARN_PRINTS("Case mismatch opening requested file '" + base_file + "', stored as '" + fname + "' in the filesystem. This file will not open when exported to other case-sensitive platforms.");
				}
			}
			FindClose(f);
		}
	}
#endif

	if (is_backup_save_enabled() && p_mode_flags & WRITE && !(p_mode_flags & READ)) {
		save_path = path;
		path = path + ".tmp";
	}

	_wfopen_s(&f, path.c_str(), mode_string);

	if (f == NULL) {
		last_error = ERR_FILE_CANT_OPEN;
		return ERR_FILE_CANT_OPEN;
	} else {
		last_error = OK;
		flags = p_mode_flags;
		return OK;
	}
}
Пример #16
0
Error AudioDriverPulseAudio::init_device() {

	// If there is a specified device check that it is really present
	if (device_name != "Default") {
		Array list = get_device_list();
		if (list.find(device_name) == -1) {
			device_name = "Default";
			new_device = "Default";
		}
	}

	// Detect the amount of channels PulseAudio is using
	// Note: If using an even amount of channels (2, 4, etc) channels and pa_map.channels will be equal,
	// if not then pa_map.channels will have the real amount of channels PulseAudio is using and channels
	// will have the amount of channels Godot is using (in this case it's pa_map.channels + 1)
	detect_channels();
	switch (pa_map.channels) {
		case 1: // Mono
		case 3: // Surround 2.1
		case 5: // Surround 5.0
		case 7: // Surround 7.0
			channels = pa_map.channels + 1;
			break;

		case 2: // Stereo
		case 4: // Surround 4.0
		case 6: // Surround 5.1
		case 8: // Surround 7.1
			channels = pa_map.channels;
			break;

		default:
			WARN_PRINTS("PulseAudio: Unsupported number of channels: " + itos(pa_map.channels));
			pa_channel_map_init_stereo(&pa_map);
			channels = 2;
			break;
	}

	int latency = GLOBAL_DEF_RST("audio/output_latency", DEFAULT_OUTPUT_LATENCY);
	buffer_frames = closest_power_of_2(latency * mix_rate / 1000);
	pa_buffer_size = buffer_frames * pa_map.channels;

	print_verbose("PulseAudio: detected " + itos(pa_map.channels) + " channels");
	print_verbose("PulseAudio: audio buffer frames: " + itos(buffer_frames) + " calculated latency: " + itos(buffer_frames * 1000 / mix_rate) + "ms");

	pa_sample_spec spec;
	spec.format = PA_SAMPLE_S16LE;
	spec.channels = pa_map.channels;
	spec.rate = mix_rate;

	pa_str = pa_stream_new(pa_ctx, "Sound", &spec, &pa_map);
	if (pa_str == NULL) {
		ERR_PRINTS("PulseAudio: pa_stream_new error: " + String(pa_strerror(pa_context_errno(pa_ctx))));
		ERR_FAIL_V(ERR_CANT_OPEN);
	}

	pa_buffer_attr attr;
	// set to appropriate buffer length (in bytes) from global settings
	// Note: PulseAudio defaults to 4 fragments, which means that the actual
	// latency is tlength / fragments. It seems that the PulseAudio has no way
	// to get the fragments number so we're hardcoding this to the default of 4
	const int fragments = 4;
	attr.tlength = pa_buffer_size * sizeof(int16_t) * fragments;
	// set them to be automatically chosen
	attr.prebuf = (uint32_t)-1;
	attr.maxlength = (uint32_t)-1;
	attr.minreq = (uint32_t)-1;

	const char *dev = device_name == "Default" ? NULL : device_name.utf8().get_data();
	pa_stream_flags flags = pa_stream_flags(PA_STREAM_INTERPOLATE_TIMING | PA_STREAM_ADJUST_LATENCY | PA_STREAM_AUTO_TIMING_UPDATE);
	int error_code = pa_stream_connect_playback(pa_str, dev, &attr, flags, NULL, NULL);
	ERR_FAIL_COND_V(error_code < 0, ERR_CANT_OPEN);

	samples_in.resize(buffer_frames * channels);
	samples_out.resize(pa_buffer_size);

	// Reset audio input to keep synchronisation.
	input_position = 0;
	input_size = 0;

	return OK;
}
Пример #17
0
void EditorFileSystem::_notification(int p_what) {

	switch(p_what) {

		case NOTIFICATION_ENTER_TREE: {


			   scan();
		} break;
		case NOTIFICATION_EXIT_TREE: {
			if (use_threads && thread) {
				//abort thread if in progress
				abort_scan=true;
				while(scanning)	{
					OS::get_singleton()->delay_usec(1000);
				}
				Thread::wait_to_finish(thread);
				memdelete(thread);
				thread=NULL;
				WARN_PRINTS("Scan thread aborted...");
				set_process(false);

			}

			if (filesystem)
				memdelete(filesystem);
			if (new_filesystem)
				memdelete(new_filesystem);
			filesystem=NULL;
			new_filesystem=NULL;

		} break;
		case NOTIFICATION_PROCESS: {

			if (use_threads) {

				if (scanning_sources) {

					if (scanning_sources_done) {

						scanning_sources=false;

						set_process(false);

						Thread::wait_to_finish(thread_sources);
						memdelete(thread_sources);
						thread_sources=NULL;
						if (_update_scan_actions())
							emit_signal("filesystem_changed");
						//print_line("sources changed: "+itos(sources_changed.size()));
						emit_signal("sources_changed",sources_changed.size()>0);
					}
				} else if (!scanning) {

					set_process(false);

					if (filesystem)
						memdelete(filesystem);
					filesystem=new_filesystem;
					new_filesystem=NULL;
					Thread::wait_to_finish(thread);
					memdelete(thread);
					thread=NULL;
					_update_scan_actions();
					emit_signal("filesystem_changed");
					emit_signal("sources_changed",sources_changed.size()>0);
					//print_line("initial sources changed: "+itos(sources_changed.size()));



				} else {
					//progress->set_text("Scanning...\n"+itos(total*100)+"%");
				}
			}
		} break;
	}

}
Пример #18
0
void godot_icall_BuildInstance_get_MSBuildInfo(MonoString **r_msbuild_path, MonoString **r_framework_path) {

	GodotSharpBuilds::BuildTool build_tool = GodotSharpBuilds::BuildTool(int(EditorSettings::get_singleton()->get("mono/builds/build_tool")));

#if defined(WINDOWS_ENABLED)
	switch (build_tool) {
		case GodotSharpBuilds::MSBUILD: {
			static String msbuild_tools_path = MonoRegUtils::find_msbuild_tools_path();

			if (msbuild_tools_path.length()) {
				if (!msbuild_tools_path.ends_with("\\"))
					msbuild_tools_path += "\\";

				// FrameworkPathOverride
				const MonoRegInfo &mono_reg_info = GDMono::get_singleton()->get_mono_reg_info();
				if (mono_reg_info.assembly_dir.length()) {
					*r_msbuild_path = GDMonoMarshal::mono_string_from_godot(msbuild_tools_path + "MSBuild.exe");

					String framework_path = path_join(mono_reg_info.assembly_dir, "mono", "4.5");
					*r_framework_path = GDMonoMarshal::mono_string_from_godot(framework_path);
				} else {
					ERR_PRINT("Cannot find Mono's assemblies directory in the registry");
				}

				return;
			}

			if (OS::get_singleton()->is_stdout_verbose())
				OS::get_singleton()->print("Cannot find System's MSBuild. Trying with Mono's...\n");
		} // fall through
		case GodotSharpBuilds::MSBUILD_MONO: {
			String msbuild_path = GDMono::get_singleton()->get_mono_reg_info().bin_dir.plus_file("msbuild.bat");

			if (!FileAccess::exists(msbuild_path)) {
				WARN_PRINTS("Cannot find msbuild ('mono/builds/build_tool'). Tried with path: " + msbuild_path);
			}

			*r_msbuild_path = GDMonoMarshal::mono_string_from_godot(msbuild_path);

			return;
		} break;
		default:
			ERR_EXPLAIN("You don't deserve to live");
			CRASH_NOW();
	}
#elif defined(UNIX_ENABLED)
	static String msbuild_path = _find_build_engine_on_unix("msbuild");
	static String xbuild_path = _find_build_engine_on_unix("xbuild");

	if (build_tool != GodotSharpBuilds::XBUILD) {
		if (msbuild_path.empty()) {
			WARN_PRINT("Cannot find msbuild ('mono/builds/build_tool').");
			return;
		}
	} else {
		if (xbuild_path.empty()) {
			WARN_PRINT("Cannot find xbuild ('mono/builds/build_tool').");
			return;
		}
	}

	*r_msbuild_path = GDMonoMarshal::mono_string_from_godot(build_tool != GodotSharpBuilds::XBUILD ? msbuild_path : xbuild_path);

	return;
#else
	ERR_PRINT("Not implemented on this platform");
	return;
#endif
}
Пример #19
0
void EditorFileSystem::_notification(int p_what) {

	switch (p_what) {

		case NOTIFICATION_ENTER_TREE: {

			call_deferred("scan"); //this should happen after every editor node entered the tree

		} break;
		case NOTIFICATION_EXIT_TREE: {
			if (use_threads && thread) {
				//abort thread if in progress
				abort_scan = true;
				while (scanning) {
					OS::get_singleton()->delay_usec(1000);
				}
				Thread::wait_to_finish(thread);
				memdelete(thread);
				thread = NULL;
				WARN_PRINTS("Scan thread aborted...");
				set_process(false);
			}

			if (filesystem)
				memdelete(filesystem);
			if (new_filesystem)
				memdelete(new_filesystem);
			filesystem = NULL;
			new_filesystem = NULL;

		} break;
		case NOTIFICATION_PROCESS: {

			if (use_threads) {

				if (scanning_changes) {

					if (scanning_changes_done) {

						scanning_changes = false;

						set_process(false);

						Thread::wait_to_finish(thread_sources);
						memdelete(thread_sources);
						thread_sources = NULL;
						if (_update_scan_actions())
							emit_signal("filesystem_changed");
						emit_signal("sources_changed", sources_changed.size() > 0);
					}
				} else if (!scanning) {

					set_process(false);

					if (filesystem)
						memdelete(filesystem);
					filesystem = new_filesystem;
					new_filesystem = NULL;
					Thread::wait_to_finish(thread);
					memdelete(thread);
					thread = NULL;
					_update_scan_actions();
					emit_signal("filesystem_changed");
					emit_signal("sources_changed", sources_changed.size() > 0);
				}
			}
		} break;
	}
}
Пример #20
0
void GDMonoClass::fetch_methods_with_godot_api_checks(GDMonoClass *p_native_base) {

	CRASH_COND(!CACHED_CLASS(GodotObject)->is_assignable_from(this));

	if (methods_fetched)
		return;

	void *iter = NULL;
	MonoMethod *raw_method = NULL;
	while ((raw_method = mono_class_get_methods(get_mono_ptr(), &iter)) != NULL) {
		StringName name = mono_method_get_name(raw_method);

		// get_method implicitly fetches methods and adds them to this->methods
		GDMonoMethod *method = get_method(raw_method, name);
		ERR_CONTINUE(!method);

		if (method->get_name() != name) {

#ifdef DEBUG_ENABLED
			String fullname = method->get_ret_type_full_name() + " " + name + "(" + method->get_signature_desc(true) + ")";
			WARN_PRINTS("Method `" + fullname + "` is hidden by Godot API method. Should be `" +
						method->get_full_name_no_class() + "`. In class `" + namespace_name + "." + class_name + "`.");
#endif
			continue;
		}

#ifdef DEBUG_ENABLED
		// For debug builds, we also fetched from native base classes as well before if this is not a native base class.
		// This allows us to warn the user here if he is using snake_case by mistake.

		if (p_native_base != this) {

			GDMonoClass *native_top = p_native_base;
			while (native_top) {
				GDMonoMethod *m = native_top->get_method(name, method->get_parameters_count());

				if (m && m->get_name() != name) {
					// found
					String fullname = m->get_ret_type_full_name() + " " + name + "(" + m->get_signature_desc(true) + ")";
					WARN_PRINTS("Method `" + fullname + "` should be `" + m->get_full_name_no_class() +
								"`. In class `" + namespace_name + "." + class_name + "`.");
					break;
				}

				if (native_top == CACHED_CLASS(GodotObject))
					break;

				native_top = native_top->get_parent_class();
			}
		}
#endif

		uint32_t flags = mono_method_get_flags(method->mono_method, NULL);

		if (!(flags & MONO_METHOD_ATTR_VIRTUAL))
			continue;

		// Virtual method of Godot Object derived type, let's try to find GodotMethod attribute

		GDMonoClass *top = p_native_base;

		while (top) {
			GDMonoMethod *base_method = top->get_method(name, method->get_parameters_count());

			if (base_method && base_method->has_attribute(CACHED_CLASS(GodotMethodAttribute))) {
				// Found base method with GodotMethod attribute.
				// We get the original API method name from this attribute.
				// This name must point to the virtual method.

				MonoObject *attr = base_method->get_attribute(CACHED_CLASS(GodotMethodAttribute));

				StringName godot_method_name = CACHED_FIELD(GodotMethodAttribute, methodName)->get_string_value(attr);
#ifdef DEBUG_ENABLED
				CRASH_COND(godot_method_name == StringName());
#endif
				MethodKey key = MethodKey(godot_method_name, method->get_parameters_count());
				GDMonoMethod **existing_method = methods.getptr(key);
				if (existing_method)
					memdelete(*existing_method); // Must delete old one
				methods.set(key, method);

				break;
			}

			if (top == CACHED_CLASS(GodotObject))
				break;

			top = top->get_parent_class();
		}
	}

	methods_fetched = true;
}
Пример #21
0
Error AudioDriverWASAPI::init_device(bool reinit) {

	WAVEFORMATEX *pwfex;
	IMMDeviceEnumerator *enumerator = NULL;
	IMMDevice *device = NULL;

	CoInitialize(NULL);

	HRESULT hr = CoCreateInstance(CLSID_MMDeviceEnumerator, NULL, CLSCTX_ALL, IID_IMMDeviceEnumerator, (void **)&enumerator);
	ERR_FAIL_COND_V(hr != S_OK, ERR_CANT_OPEN);

	hr = enumerator->GetDefaultAudioEndpoint(eRender, eConsole, &device);
	if (reinit) {
		// In case we're trying to re-initialize the device prevent throwing this error on the console,
		// otherwise if there is currently no device available this will spam the console.
		if (hr != S_OK) {
			return ERR_CANT_OPEN;
		}
	} else {
		ERR_FAIL_COND_V(hr != S_OK, ERR_CANT_OPEN);
	}

	hr = enumerator->RegisterEndpointNotificationCallback(&notif_client);
	if (hr != S_OK) {
		ERR_PRINT("WASAPI: RegisterEndpointNotificationCallback error");
	}

	hr = device->Activate(IID_IAudioClient, CLSCTX_ALL, NULL, (void **)&audio_client);
	if (reinit) {
		if (hr != S_OK) {
			return ERR_CANT_OPEN;
		}
	} else {
		ERR_FAIL_COND_V(hr != S_OK, ERR_CANT_OPEN);
	}

	hr = audio_client->GetMixFormat(&pwfex);
	ERR_FAIL_COND_V(hr != S_OK, ERR_CANT_OPEN);

	// Since we're using WASAPI Shared Mode we can't control any of these, we just tag along
	wasapi_channels = pwfex->nChannels;
	mix_rate = pwfex->nSamplesPerSec;
	format_tag = pwfex->wFormatTag;
	bits_per_sample = pwfex->wBitsPerSample;

	switch (wasapi_channels) {
		case 2: // Stereo
			//case 6: // Surround 5.1
			//case 8: // Surround 7.1
			channels = wasapi_channels;
			break;

		default:
			WARN_PRINTS("WASAPI: Unsupported number of channels (" + itos(wasapi_channels) + ")");
			channels = 2;
	}

	if (format_tag == WAVE_FORMAT_EXTENSIBLE) {
		WAVEFORMATEXTENSIBLE *wfex = (WAVEFORMATEXTENSIBLE *)pwfex;

		if (wfex->SubFormat == KSDATAFORMAT_SUBTYPE_PCM) {
			format_tag = WAVE_FORMAT_PCM;
		} else if (wfex->SubFormat == KSDATAFORMAT_SUBTYPE_IEEE_FLOAT) {
			format_tag = WAVE_FORMAT_IEEE_FLOAT;
		} else {
			ERR_PRINT("WASAPI: Format not supported");
			ERR_FAIL_V(ERR_CANT_OPEN);
		}
	} else {
		if (format_tag != WAVE_FORMAT_PCM && format_tag != WAVE_FORMAT_IEEE_FLOAT) {
			ERR_PRINT("WASAPI: Format not supported");
			ERR_FAIL_V(ERR_CANT_OPEN);
		}
	}

	hr = audio_client->Initialize(AUDCLNT_SHAREMODE_SHARED, AUDCLNT_STREAMFLAGS_EVENTCALLBACK, 0, 0, pwfex, NULL);
	ERR_FAIL_COND_V(hr != S_OK, ERR_CANT_OPEN);

	event = CreateEvent(NULL, FALSE, FALSE, NULL);
	ERR_FAIL_COND_V(event == NULL, ERR_CANT_OPEN);

	hr = audio_client->SetEventHandle(event);
	ERR_FAIL_COND_V(hr != S_OK, ERR_CANT_OPEN);

	hr = audio_client->GetService(IID_IAudioRenderClient, (void **)&render_client);
	ERR_FAIL_COND_V(hr != S_OK, ERR_CANT_OPEN);

	UINT32 max_frames;
	hr = audio_client->GetBufferSize(&max_frames);
	ERR_FAIL_COND_V(hr != S_OK, ERR_CANT_OPEN);

	// Due to WASAPI Shared Mode we have no control of the buffer size
	buffer_frames = max_frames;

	// Sample rate is independent of channels (ref: https://stackoverflow.com/questions/11048825/audio-sample-frequency-rely-on-channels)
	buffer_size = buffer_frames * channels;
	samples_in.resize(buffer_size);

	if (OS::get_singleton()->is_stdout_verbose()) {
		print_line("audio buffer frames: " + itos(buffer_frames) + " calculated latency: " + itos(buffer_frames * 1000 / mix_rate) + "ms");
	}

	return OK;
}