Beispiel #1
0
/**
 * \brief Frees the program.
 *
 * \param self Program.
 */
void limai_program_free (
	LIMaiProgram* self)
{
	int i;
	LIMaiExtension* extension;
	LIMaiExtension* extension_next;
	LIMaiEvent* event;
	LIMaiEvent* event_next;
	LIMaiMessage* message;
	LIMaiMessage* message_next;

	/* Invoke callbacks. */
	if (self->callbacks != NULL)
		lical_callbacks_call (self->callbacks, "program-shutdown", lical_marshal_DATA);

	/* Free script. */
	if (self->script != NULL)
		liscr_script_free (self->script);

	/* Free extensions. */
	if (self->extensions != NULL)
	{
		for (extension = self->extensions ; extension != NULL ; extension = extension_next)
		{
			extension_next = extension->next;
			((void (*)(void*)) extension->info->free) (extension->object);
			if (extension->module != NULL)
				lisys_module_free (extension->module);
			lisys_free (extension);
		}
	}

	/* Free components. */
	if (self->components != NULL)
	{
		lisys_assert (self->components->size == 0);
		lialg_strdic_free (self->components);
	}

	/* Free the model manager. */
	if (self->models != NULL)
		limdl_manager_free (self->models);

	/* Invoke callbacks. */
	if (self->callbacks != NULL)
		lical_callbacks_call (self->callbacks, "program-free", lical_marshal_DATA);

	/* Free callbacks. */
	if (self->callbacks != NULL)
	{
		lical_handle_releasev (self->calls, sizeof (self->calls) / sizeof (LICalHandle));
		lical_callbacks_free (self->callbacks);
	}

	if (self->paths != NULL)
		lipth_paths_free (self->paths);

	/* Free messaging. */
	if (self->message_mutex != NULL)
		lisys_mutex_free (self->message_mutex);
	for (i = 0 ; i < LIMAI_MESSAGE_QUEUE_MAX ; i++)
	{
		for (message = self->messages[i] ; message != NULL ; message = message_next)
		{
			message_next = message->next;
			limai_message_free (message);
		}
	}

	/* Free events. */
	for (event = self->events_first ; event != NULL ; event = event_next)
	{
		event_next = event->next;
		limai_event_free (event);
	}

	lisys_free (self->launch_args);
	lisys_free (self->launch_name);
	lisys_free (self->args);
	lisys_free (self);
}
Beispiel #2
0
/**
 * \brief Creates a new paths object.
 *
 * \param path Package root directory or NULL for auto-detect.
 * \param name Module name.
 * \return Paths or NULL.
 */
LIPthPaths* lipth_paths_new (
	const char* path,
	const char* name)
{
	char* tmp;
	LIPthPaths* self;

	/* Allocate self. */
	self = lisys_calloc (1, sizeof (LIPthPaths));
	if (self == NULL)
		return NULL;

	/* Allocate the file lookup table. */
	self->files = lialg_strdic_new ();
	if (self->files == NULL)
	{
		lipth_paths_free (self);
		return NULL;
	}

	/* Set the module name. */
	self->module_name = lisys_string_dup (name);
	if (self->module_name == NULL)
	{
		lipth_paths_free (self);
		return NULL;
	}

	/* Set the root directory. */
	if (path != NULL)
	{
		self->root = lisys_string_dup (path);
		if (self->root == NULL)
		{
			lipth_paths_free (self);
			return NULL;
		}
	}
	else
	{
		self->root = lipth_paths_get_root ();
		if (self->root == NULL)
		{
			lipth_paths_free (self);
			return NULL;
		}
	}

	/* Get the data directory root. */
	/* This is where modules and system scripts are located. If relative paths
	   are enabled, the directory of the executable is searched for a data
	   directory. Failing that, XDG data directories are searched for the game
	   directory. As the last resort, the hardcoded data directory is used. */
#ifdef LI_RELATIVE_PATHS
	self->global_data = lisys_path_concat (self->root, "data", NULL);
	if (!private_validate_dir (&self->global_data))
#endif
	{
		self->global_data = lisys_paths_get_data_global ("lipsofsuna");
		private_validate_dir (&self->global_data);
		if (self->global_data == NULL)
		{
#ifdef LIDATADIR
			self->global_data = lisys_string_dup (LIDATADIR);
			if (!private_validate_dir (&self->global_data))
#endif
			{
				lisys_error_set (EINVAL, "cannot find the data directory");
				lipth_paths_free (self);
				return NULL;
			}
		}
	}

	/* Get the data directory of the current module. */
	/* This is where the data files of the module are installed. The directory
	   functions as a fallback for both data and configuration files. */
	self->module_data = lisys_path_concat (self->global_data, name, NULL);
	if (!private_validate_dir (&self->module_data))
	{
		lisys_error_set (EINVAL, "cannot find the module data directory");
		lipth_paths_free (self);
		return NULL;
	}

	/* Get the data save directory. */
	/* This is where save files are written and where the user can copy any
	   custom data files or mods. It's the first place where data files are
	   looked for. */
	tmp = lisys_paths_get_data_home ();
	if (tmp == NULL)
	{
		lipth_paths_free (self);
		return NULL;
	}
	self->module_data_save = lisys_path_concat (tmp, "lipsofsuna", name, NULL);
	lisys_free (tmp);
	if (self->module_data_save == NULL)
	{
		lipth_paths_free (self);
		return NULL;
	}

	/* Get the config directory. */
	/* This is where configuration files are stored. It's separate from the save
	   directory since in Linux that's the case. In Windows it's actually the
	   save directory. */
	tmp = lisys_paths_get_config_home ();
	if (tmp == NULL)
	{
		lipth_paths_free (self);
		return NULL;
	}
	self->module_config = lisys_path_concat (tmp, "lipsofsuna", name, NULL);
	lisys_free (tmp);
	if (self->module_config == NULL)
	{
		lipth_paths_free (self);
		return NULL;
	}

	/* Get the extension directory. */
	/* This directory is reserved for potential third party extension libraries.
	   The path is lib/extensions either in the relative path, XDG data path or
	   the hardcoded extension directory. */
#ifdef LI_RELATIVE_PATHS
	self->global_exts = lisys_path_concat (self->global_data, "lib", "extensions", NULL);
	if (!private_validate_dir (&self->global_exts))
#endif
	{
		self->global_exts = lisys_paths_get_data_global ("lipsofsuna/lib/extensions");
#ifdef LIEXTSDIR
		if (!private_validate_dir (&self->global_exts))
		{
			self->global_exts = lisys_string_dup (LIEXTSDIR);
			private_validate_dir (&self->global_exts);
		}
#endif
	}

	/* Create the save directories. */
	if (!private_create_save_path (self, self->module_data_save) ||
	    !private_create_save_path (self, self->module_config))
	{
		lipth_paths_free (self);
		return NULL;
	}

	/* Add the base data directory. */
	lipth_paths_add_path (self, "");

	return self;
}
Beispiel #3
0
/**
 * \brief Creates a new paths object.
 *
 * \param path Package root directory or NULL for auto-detect.
 * \param name Module name.
 * \return Paths or NULL.
 */
LIPthPaths* lipth_paths_new (
	const char* path,
	const char* name)
{
	char* tmp;
	LIPthPaths* self;
	LISysStat stat;

	self = lisys_calloc (1, sizeof (LIPthPaths));
	if (self == NULL)
		return NULL;

	/* Set module name. */
	self->module_name = lisys_string_dup (name);
	if (self->module_name == NULL)
		goto error;

	/* Set root directory. */
	if (path != NULL)
	{
		self->root = lisys_string_dup (path);
		if (self->root == NULL)
			goto error;
	}
	else
	{
		self->root = lipth_paths_get_root ();
		if (self->root == NULL)
			goto error;
	}

	/* Get data directory. */
#ifdef LI_RELATIVE_PATHS
	self->global_data = lisys_path_concat (self->root, "data", NULL);
	if (self->global_data == NULL)
		goto error;
#else
	self->global_data = LIDATADIR;
#endif
	self->module_data = lisys_path_concat (self->global_data, name, NULL);
	if (self->module_data == NULL)
		goto error;

	/* Get data override directory. */
	tmp = lisys_paths_get_data_home ();
	if (tmp == NULL)
		goto error;
	self->override_data = lisys_path_concat (tmp, "lipsofsuna", "data", name, NULL);
	if (self->override_data == NULL)
	{
		lisys_free (tmp);
		goto error;
	}

	/* Get save directory. */
	self->global_state = lisys_path_concat (tmp, "lipsofsuna", "save", NULL);
	lisys_free (tmp);
	if (self->global_state == NULL)
		goto error;
	self->module_state = lisys_path_concat (self->global_state, name, NULL);
	if (self->module_state == NULL)
		goto error;

	/* Get extension directory. */
#ifdef LI_RELATIVE_PATHS
	self->global_exts = lisys_path_concat (self->global_data, "lib", "extensions", NULL);
	if (self->global_exts == NULL)
		goto error;
#else
	self->global_exts = LIEXTSDIR;
#endif

	/* Check for valid data directory. */
	if (!lisys_filesystem_stat (self->module_data, &stat))
	{
		lisys_error_set (EIO, "missing data directory `%s'", self->module_data);
		goto error;
	}
	if (stat.type != LISYS_STAT_DIRECTORY && stat.type != LISYS_STAT_LINK)
	{
		lisys_error_set (EIO, "invalid data directory `%s': not a directory", self->module_data);
		goto error;
	}

	return self;

error:
	lipth_paths_free (self);
	return NULL;
}