dillon@CORY.BERKELEY.EDU (Matt Dillon) (06/06/88)
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 "<blah>.EDIT" which, when executed, edits the specified resource: Resource to Edit: Name = <SomeName>, Type = <Type> Edit resource: Name = <Type.EDIT>, Type = "Code" To edit, simply: GetResource("<SomeName>", "EDIT"); -Matt
blandy@lakshmi.cs.cornell.edu (Jim Blandy) (06/09/88)
In article <8806052331.AA28897@cory.Berkeley.EDU> dillon@CORY.BERKELEY.EDU (Matt Dillon) writes: > > As you all know, My big project right now is the implementation >of resources ... > 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: [ ... description of standard code resources which convert one type of resource to another ... ] That is a completely fantastic idea, Matt. I'd steal your brain in a second, if I could use it. It's similar to the way 'make' can assume how to get a .o file from a .c file without being specific to C or whatever. >(1) What if I want to implement a system-default window? ... [ ... stuff on shared resources and things, looking a bit like a solicitation of suggestions :-) ...] > -Matt The way I see it, the conversion resources take a resource of one type and make a new resource of the asked-for type. So if this converter makes a Window out of a shared NewWindow, the Window so created is shared too; it's a genuine resource, just like anything else. You're maintaining a "shared resources currently in memory" list, so put this new Window resource on the list; the next person that asks for it finds the already-opened window. In the general case: if a shared wombat_description is turned into a wombat by some conversion resource (called wombat_description.wombat), then that new wombat is also a shared resource, to be added to the "shared resources in memory" list; other programs calling GetResource() for that same wombat will be given the same value the first one did. (PS - where can I get a copy of MDE, and the Fred Fish listings?) Jim Blandy - blandy@crnlcs.bitnet "insects were insects when man was just a burbling whatsit." - archie