Path: utzoo!utgpu!water!watmath!clyde!bellcore!rutgers!gatech!udel!rochester!bbn!uwmcsd1!ig!agate!ucbvax!CORY.BERKELEY.EDU!dillon
From: dillon@CORY.BERKELEY.EDU (Matt Dillon)
Newsgroups: comp.sys.amiga.tech
Subject: Resources, Take 3
Message-ID: <8806052331.AA28897@cory.Berkeley.EDU>
Date: 5 Jun 88 23:31:21 GMT
Sender: daemon@ucbvax.BERKELEY.EDU
Lines: 168
As you all know, My big project right now is the implementation
of resources (remote reference to Mac-like resources). I've gone through
many schemes, some of which I've posted.
Well, I've been stupid. I've been going about it the wrong way
entirely ... that old saying about making things as simple as possible?
Well, it applies here in all respects.
Originally, my idea was to have this incredibly complex system
whereby resources have a 'structure' which determines various things, like
memory type requirements and what needs to be relocated and what does not.
This requires a huge convoluted structure and lots of complex code to
implement.
The *right* way to do it is to essentially have a relatively
simple storage format, and then make the entire system object oriented.
So here is my *new* idea on the subject:
(1) Where are they?
Resources can be in separate files, or part of an executable. If
part of an executable the resources are assumed to be immediately
required by the executable and all loaded into memory. It is
assumed the program will be requested almost all of them.
If not part of an executable (i.e. in a separate file), only
specifically requested resources are loaded from that file. i.e.
resources are loaded on demand.
Resources can be both in the executable and elsewhere. For instance,
there will be one or more 'system global' resource files which are
available for use.
(2) Features of the resource system.
Resources can either be private to an application (only that
application and multiple invocations of that application see the
resource), or global (any process in the system can see the resource)
Resources can either be shared or non-shared. A shared resource
exists in RAM once ... multiple references refer to the same
physical memory. memory for a resource which is not shared is
allocated every time it is requested.
A resource consists of:
(1) A resource-name
(2) A resource-type (which is also a name)
(3) bulk data pertaining to the resource
---------------
Now, I want to be able to do something like:
GetResource("MyWindow", "Window");
Where "MyWindow" is the resource name and "Window" is the resource
type... i.e. an intuition window. But I want this to work even if
the resource on disk is actually:
resource MyWindow is type NewWindow
In otherwords, when I do the GetResource(), the system should notice
that I want a Window but it can only find a NewWindow, and
automatically OpenWindow() the structure for me. How does one
accomplish this generically? Remember that resources *ARE* general
in that the resource-types are not necessarily just those in
the Amiga include's ... people will want to make their own custom
resources.
Solution:
There exists a special resource, usually GLOBAL and SHARED with the
following specifications:
Name = "FromType.ToType" (e.g. "NewWindow.Window")
Type = "Code"
Contents = Relocatable code that converts a resource of 'FromType'
to a resource of 'ToType'
Such resources are usually system global resources. Thus, if a
resource "NewWindow.Window" of type "Code" exists my request can
be properly performed.
----------------------------------------------------------------------
You've got to understand what I've discussed above before reading
on. Now there are a couple of items that need to be addressed which I
have yet to work out fully:
(1) What if I want to implement a system-default window? The resource
on disk will be something like: name="SysWindow" type="NewWindow",
and programs will get the resource via
struct Window *win = GetResource("SysWindow","Window"),
Thus returning an intuition Window. BUT I WANT ANOTHER PROGRAM
WHICH MAKES THE SAME REQUEST TO RETURN THE ALREADY OPENNED WINDOW!
So I will need to develope an intuitive mechanism that allows such
conversions to either be SHARED (don't re-open the window just return
the already openned window) or NOT-SHARED. The "SysWindow" resource
is, of course, system global and shared, but this 'shared'ness is
different ... it simply means the NewWindow structure itself is
shared, not necessarily the resultant structure after you apply a
conversion.
Obviously, both flavors are wanted: (1) Where the GetResource()
call takes the NewWindow structure and opens a new window on
every reference, and (2) Where the GetResource() call takes the
NewWindow structure, but if the window has already been openned
simply returns the window, keeping a reference count on usage.
(2) References. A shared resource will have a reference count. Thus,
after all users of the "SysWindow" resource are done using it,
the window will go away... or will it?
(3) Disk swapping and memory usage. Do we want resources to be swapped
to some auxillary storage if they remain unused for long periods of
time? Taking the above example, do we want that SysWindow to stay
open until the system either begins to run out of memory or it
remains unused for a long time?
A better example might be a device driver or font ...
(4) Other special resources and relocation. I suggest the following:
Lets say you have a resource of type "List". When you
GetResource() it you don't just want a List pointer, but an
initialized List pointer... you don't want to have to NewList() it.
It makes sense (at least to me), to do this:
The resource on disk will have a type "_List", not "List". There
will then be a conversion resource whos name is: "List._List".
So when I GetResource("MyList", "List") it will find "_List" and
then do the conversion to "List".
NOTE AWESOME POWER! No matter whether a resource needs to be
converted or fixed up or whatever, the program always requests
the resource by it's PROPER TYPE. The only time a program would
ever GetResource("MyList", "_List") would be if it wants the raw
data!
NOTE AWESOME POWER2! Lets say you want to have a buffer resource...
say 4K (the reason it's a resource in the first place is because
you want the user to be able to modify the size of the buffer).
It makes no sense to have 4K of nothing in a file. But wait! how
about make a custom resource called "_Buffer" which contains two
longwords: a buffer size and a memory type.
Then, when you request "MyBuffer", "Buffer", the conversion resource
will take those measily 8 bytes, call AllocMem(), and return to you
a pointer to the specified amount of memory!
NOTE AWSOME POWER3! Lets say you want to allow the user to EDIT
one of your custom resources. Easy! Just have a resource of
type "Code" whos name is ".EDIT" which, when executed, edits
the specified resource:
Resource to Edit: Name = , Type =
Edit resource: Name = , Type = "Code"
To edit, simply: GetResource("", "EDIT");
-Matt