1
0
Fork 0
mirror of https://github.com/ganelson/inform.git synced 2024-04-27 14:49:34 +03:00
inform7/inform7/multimedia-module/Chapter 2/Internal Files.w
2022-11-07 22:41:51 +00:00

135 lines
4.4 KiB
OpenEdge ABL

[InternalFiles::] Internal Files.
To register the names associated with internal files, and build
the small I6 arrays associated with each.
@ The following is called to activate the feature:
=
void InternalFiles::start(void) {
PluginCalls::plug(PRODUCTION_LINE_PLUG, InternalFiles::production_line);
PluginCalls::plug(NEW_BASE_KIND_NOTIFY_PLUG, InternalFiles::files_new_base_kind_notify);
PluginCalls::plug(NEW_INSTANCE_NOTIFY_PLUG, InternalFiles::files_new_named_instance_notify);
}
int InternalFiles::production_line(int stage, int debugging,
stopwatch_timer *sequence_timer) {
if (stage == INTER1_CSEQ) {
BENCH(RTMultimedia::compile_internal_files);
}
return FALSE;
}
@h One significant kind.
= (early code)
kind *K_internal_file = NULL;
@ =
int InternalFiles::files_new_base_kind_notify(kind *new_base, text_stream *name, wording W) {
if (Str::eq_wide_string(name, L"INTERNAL_FILE_TY")) {
K_internal_file = new_base; return TRUE;
}
return FALSE;
}
@h Significant new instances.
This structure of additional data is attached to each figure instance.
=
typedef struct internal_files_data {
struct wording name; /* text of name */
int unextended_filename; /* word number of text like |"ice extents.usgs"| */
struct filename *local_filename; /* of where this file is, in Materials directory */
struct text_stream *inf_identifier; /* an Inter identifier */
int file_format; /* |INTERNAL_TEXT_FILE_NFSMF| or |INTERNAL_BINARY_FILE_NFSMF| */
struct instance *as_instance;
struct parse_node *where_created;
int resource_id;
CLASS_DEFINITION
} internal_files_data;
@ We allow instances of "internal file" to be created only through the code
from //External Files// calling //InternalFiles::files_create//. If any other
proposition somehow manages to make a file, a problem message is thrown.
=
int allow_inf_creations = FALSE;
instance *InternalFiles::files_create(int format, wording W, wording FN) {
allow_inf_creations = TRUE;
Assert::true(Propositions::Abstract::to_create_something(K_internal_file, W), CERTAIN_CE);
allow_inf_creations = FALSE;
instance *I = Instances::latest();
internal_files_data *ifd = FEATURE_DATA_ON_INSTANCE(internal_files, I);
ifd->name = W;
ifd->unextended_filename = Wordings::first_wn(FN);
ifd->file_format = format;
ifd->where_created = current_sentence;
ifd->as_instance = I;
ifd->resource_id = Task::get_next_free_blorb_resource_ID();
TEMPORARY_TEXT(leaf)
Word::dequote(Wordings::first_wn(FN));
WRITE_TO(leaf, "%N", Wordings::first_wn(FN));
ifd->local_filename = Filenames::in(Task::data_path(), leaf);
DISCARD_TEXT(leaf)
return I;
}
int InternalFiles::files_new_named_instance_notify(instance *I) {
if (K_internal_file == NULL) return FALSE;
kind *K = Instances::to_kind(I);
if (Kinds::eq(K, K_internal_file)) {
if (allow_inf_creations == FALSE)
StandardProblems::sentence_problem(Task::syntax_tree(),
_p_(PM_BackdoorInternalFileCreation),
"this is not the way to create a new internal file",
"which should be done with a special 'The internal data file "
"... is called ...' sentence.");
ATTACH_FEATURE_DATA_TO_SUBJECT(internal_files, I->as_subject, CREATE(internal_files_data));
return TRUE;
}
return FALSE;
}
@h Blurb and manifest.
The i-files manifest is used by the implementation of Glulx within the Inform
application to connect file ID numbers with filenames relative to the
|.materials| folder for its project. (It's part of the XML manifest file
created from |Figures.w|.)
=
void InternalFiles::write_files_manifest(OUTPUT_STREAM) {
if (K_internal_file == NULL) return;
internal_files_data *ifd;
if (NUMBER_CREATED(internal_files_data) == 0) return;
WRITE("<key>Data</key>\n");
WRITE("<dict>\n"); INDENT;
LOOP_OVER(ifd, internal_files_data) {
WRITE("<key>%d</key>\n", ifd->resource_id);
TEMPORARY_TEXT(rel)
Filenames::to_text_relative(rel, ifd->local_filename,
Projects::materials_path(Task::project()));
WRITE("<string>%S</string>\n", rel);
DISCARD_TEXT(rel)
}
OUTDENT; WRITE("</dict>\n");
}
@ The following writes Blurb commands for all of the internal files.
=
void InternalFiles::write_blurb_commands(OUTPUT_STREAM) {
if (K_internal_file == NULL) return;
internal_files_data *ifd;
LOOP_OVER(ifd, internal_files_data) {
WRITE("data %d \"%f\" type ", ifd->resource_id, ifd->local_filename);
switch (ifd->file_format) {
case INTERNAL_TEXT_FILE_NFSMF: WRITE("TEXT"); break;
case INTERNAL_BINARY_FILE_NFSMF: WRITE("BINA"); break;
}
WRITE("\n");
}
}