Converters (merged with Converters Docu)

User avatar
DGDanforth
Posts: 1061
Joined: Tue Sep 17, 2013 1:16 am
Location: Palo Alto, California, USA
Contact:

Converters (merged with Converters Docu)

Post by DGDanforth »

Three changes need to be made to Converters.
(1) Documentation (changed)
(2) GetLastRegistered (added)
(3) Deregister (added)

The motivation for those changes is that the documentation is misleading. It suggests modifications to Config.odc are necessary in order to added new converters to the BB framework. That is false. New converters can be added by any module. That evokes the idea "If one creates, one must destroy" and hence the need to remove a converter from the converter's registry. To do that one needs a handle to the converter created when one calls Converters.Register. To get that handle I suggest to add the procedure "GetLastRegistered" along with the following modifications to Converters.

Code: Select all

	Converter* = POINTER TO RECORD
		id:	INTEGER; (*added*)
		next-: Converter;
		imp-, exp-: Dialog.String;
		storeType-: Stores.TypeName;
		fileType-: Files.Type;
		opts-: SET
	END;

Code: Select all

	VAR
		list-: Converter;
		doc: Converter;
		numId: INTEGER; (*added*)

Code: Select all

	PROCEDURE Register* (imp, exp: Dialog.String; storeType: Stores.TypeName; fileType: Files.Type; opts: SET);
		VAR e, f: Converter;
	BEGIN
		ASSERT((imp # "") OR (exp # ""), 20); ASSERT(fileType # "", 21);
		NEW(e); e.next := NIL;
		e.id := numId; INC(numId); (*added*)
		e.imp := imp; e.exp := exp; e.fileType := fileType; e.storeType := storeType; e.opts := opts;
		IF (storeType = "") & (doc = NIL) THEN doc := e END;
		IF list = NIL THEN list := e
		ELSE f := list;
			WHILE f.next # NIL DO f := f.next END;
			f.next := e;
		END
	END Register;

Code: Select all

	PROCEDURE Clone (c: Converter): Converter; (*added*)
		VAR e: Converter;
	BEGIN
		NEW(e);
		e^ := c^;
		RETURN e
	END Clone;

Code: Select all

	PROCEDURE GetLastRegistered* (VAR c: Converter); (*added*)
		VAR e, f: Converter;
	BEGIN
		IF list # NIL THEN
			f := list;
			WHILE f.next # NIL DO f := f.next END;
			e := Clone(f); e.next := c; c := e; (*push*)
		END
	END GetLastRegistered;
Sequential calls to GetLastRegistered will build a list of converters added. The suggested usage is
Register
GetLastRegistered
Register
GetLastRegistered
...
Register
GetLastRegistered

Given a Converters.Converter (list) one can "Deregister" the list

Code: Select all

	PROCEDURE Deregister* (VAR c: Converter); (*added*)
		VAR f: Converter;
	BEGIN
		WHILE c # NIL DO
			f := list;
			WHILE (f # NIL) & (f.id # c.id) DO f := f.next END;
			IF f # NIL THEN f := f.next; DEC(numId) END; (*delete c from list*)
			c := c.next
		END
	END Deregister;

Code: Select all

	BEGIN
	list := NIL;
	numId := 0
	END Converters.
The suggested changes to the documentation are

PROCEDURE Register (imp, exp: Dialog.String; storeType: Stores.TypeName;
fileType: Files.Type; opts: SET)
Register an importer which translates a file of type fileType into a store of type storeType (e.g., "TextViews.View"), an exporter which translates a store of type storeType into a file of type fileType, or both.
imp is the name of an importer command, which must have the signature of Importer.
exp is the name of an exporter command, which must have the signature of Exporter.
opts allows to express a set of options; currently only the element importAll is defined. Normally, opts is empty.
Register does not yet load the modules which contain the import/export commands. They are loaded only when needed.
The standard document converter is already installed by the BlackBox core. Other converters may be installed in any module the Config module, e.g., converters for ASCII files, Unicode files, or picture files. Config is executed upon startup of BlackBox to allow the establishment of custom configurations, such as the set of available converters.
As a result of Register, a new converter is appended to list, with fields corresponding to the parameters passed.
For each registered importer or exporter, there optionally may be a corresponding string mapping; to make the display of a list of importers/exporters more user-friendly. For example, the importer "HostTextConv.ImportText" could be mapped to the more telling name "Ascii" (in the standard file open dialog). The mapping is done in the Strings file in the Rsrc directory of the importer's subsystem, e.g., there may be the following lines in the Host/Rsrc/Strings text:

HostTextConv.ImportText Ascii
HostTextConv.ExportText Ascii

Pre
imp # "" OR exp # "" 20
fileType # "" 21
User avatar
Robert
Posts: 1024
Joined: Sat Sep 28, 2013 11:04 am
Location: Edinburgh, Scotland

Re: Converters

Post by Robert »

DGDanforth wrote:

Code: Select all

	PROCEDURE Clone (c: Converter): Converter; (*added*)
		VAR e: Converter;
	BEGIN
		NEW(e);
		e^ := c^;
		RETURN e
	END Clone;
Is this safe?. What if c contains pointers to private data structures?
Ivan Denisov
Posts: 1700
Joined: Tue Sep 17, 2013 12:21 am
Location: Russia

Re: Converters

Post by Ivan Denisov »

I agree that converters system can be done better. Let's discuss this and design some improvements. However I am suggesting to include this in 1.8 release.
User avatar
DGDanforth
Posts: 1061
Joined: Tue Sep 17, 2013 1:16 am
Location: Palo Alto, California, USA
Contact:

Re: Converters

Post by DGDanforth »

Robert wrote:
DGDanforth wrote:

Code: Select all

	PROCEDURE Clone (c: Converter): Converter; (*added*)
		VAR e: Converter;
	BEGIN
		NEW(e);
		e^ := c^;
		RETURN e
	END Clone;
Is this safe?. What if c contains pointers to private data structures?
It doesn't but I am not happen with this solution. Alternatively one can export a new list, something like
TYPE
Added* POINTER TO RECORD id: INTEGER; next: Added END;
and then have GetLastRegistered (VAR added: Added) and Deregister(VAR added: Added)
That avoids the use of Clone and is simpler. The down side is users would need to have a variable list: Converters.Added rather than just
list: Converters.Converter;

-Doug
User avatar
DGDanforth
Posts: 1061
Joined: Tue Sep 17, 2013 1:16 am
Location: Palo Alto, California, USA
Contact:

Re: Converters

Post by DGDanforth »

Ivan Denisov wrote:I agree that converters system can be done better. Let's discuss this and design some improvements. However I am suggesting to include this in 1.8 release.
Ivan,
OK but I would hope unstable releases of 1.8 would happen soon after 1.7 is released.
-Doug
User avatar
Josef Templ
Posts: 2047
Joined: Tue Sep 17, 2013 6:50 am

Re: Converters

Post by Josef Templ »

Before going into the details of the extensions it should be explained why those extensions are needed.
In particular: why does anybody want to unregister a converter?

Fixing the docu is a different topic. This should be done as soon as possible.
This is a trivial activity.

- Josef
User avatar
DGDanforth
Posts: 1061
Joined: Tue Sep 17, 2013 1:16 am
Location: Palo Alto, California, USA
Contact:

Re: Converters

Post by DGDanforth »

Josef Templ wrote:Before going into the details of the extensions it should be explained why those extensions are needed.
In particular: why does anybody want to unregister a converter?

Fixing the docu is a different topic. This should be done as soon as possible.
This is a trivial activity.

- Josef
I agree that fixing the documentation should be done post haste (see my suggested change).

Motivation for deregistering (look up the distinction between unregister and deregister) a converter.
o Removal of clutter when a project is finished.
Do I really want to see .atg files when I am not using Coco?
Do I really want to see .c files when I am not using C2CP?

(Note that the same (equivalent) converter can be added many times and appear in the list many times. The converter "list" should be a "set".)

Also
If several developers use BlackBox on the same machine(s), it becomes cumbersome to save one's work and clean up after the end of each session, so that the next developer gets a "clean" system again. It is even more cumbersome to start working with a copy that hasn't been cleaned up correctly by the previous user. To solve this problem, server support is available for BlackBox.
BlackBox can be installed and maintained on one central server, while developers use an arbitrary number of client workstations on a local-area network. Preferably, each developer has his or her own working directory on the server (account).
I have only run BB on a single machine. If there are two (or more) machines (server, client) then when I register a converter is it only registered on the client or is it on the server? If it is on the server then I would see everyone else's converters. I assume that doesn't happen and that my (client) memory space is where the registration takes place.

In a single user multi tasking system, each task might want a different set of converters which disappear when the task completes.
That is one reason why I think that the registration process should be relative to a" Registry" So that Register becomes a method of the registry

Code: Select all

	PROCEDURE (r: Registry) Register* (imp, exp: Dialog.String; storeType: Stores.TypeName; fileType: Files.Type; opts: SET), NEW;
Instead of Deregister I would use

Code: Select all

 r := OpenRegistry();

and later

Code: Select all

 CloseRegistry(r);
In that way one avoids having to intersperse GetLastRegistered with Register.
Every converter is also added to the global Converters.list and removed when a registry is closed.
Note that Converters.Converter is no long a list but a stand alone POINTER TO RECORD ... END; The list is then a list of converters.

Should those changes be made?
NO, not without a lot of discussion since many modules would be invalided (but easily fixed).

-Doug
User avatar
DGDanforth
Posts: 1061
Joined: Tue Sep 17, 2013 1:16 am
Location: Palo Alto, California, USA
Contact:

Re: Converters

Post by DGDanforth »

Simple solution to converter deregistration
Change next- to next*
in the definition of a Converter.

One may then obtain the last converter by reading the Converters.list.
Name that last converter "registry".
When one is finished using all added converters one may then
set registry.next to NIL.

No need to change any code in modules that use Converters.
Those modules only need to be recompiled.

-Doug
User avatar
DGDanforth
Posts: 1061
Joined: Tue Sep 17, 2013 1:16 am
Location: Palo Alto, California, USA
Contact:

Re: Converters

Post by DGDanforth »

and perhaps this is even better.
Don't change the definition of Converters.

Just add the two procedures

Code: Select all

	PROCEDURE OpenRegistry* (): Converter;
		VAR registry: Converter;
	BEGIN
		registry := list;
		IF registry # NIL THEN
			WHILE registry.next # NIL DO registry := registry.next END;
		END;
		RETURN registry
	END OpenRegistry;

	PROCEDURE CloseRegistry* (registry: Converter);
	BEGIN
		IF registry # NIL THEN registry.next := NIL END
	END CloseRegistry;

The user may or may not choose to use OpenRegistry and CloseRegistry.
The change still requires recompilation of modules that import Converters.
-Doug
User avatar
Josef Templ
Posts: 2047
Joined: Tue Sep 17, 2013 6:50 am

Re: Converters

Post by Josef Templ »

To me a simple and meaningful extension would be to add two procedures:

PROCEDURE RegisterEx(..., OUT c: Converter);
PROCEDURE Unregister(c: Converter);

where RegisterEx can be used for registering a temporarily used converter,
i.e. one that is subject to Unregister at a later time.
Such a case is typical when developing a new converter because
multiple edit-compile-load-register cycles can be involved.
It may also be useful to shrink the converter list when an extension package is unloaded
as Doug pointed out.

The postfix 'Ex' in RegisterEx has a double meaning:
1. it refers to the fact that it is an extension of the signature of Register,
2. it will typically be used for registering extensions to Config.
That's why I like this name.

I can imagine to add a call to Unregister in the CLOSE section of a module.
Thereby a converter can be unregistered whenever the related module is unloaded.
I would not do this in the standard modules but only in extension packages.

Anything not registered in Config (or some other startup module) is temporarily available.
When you restart BlackBox it is gone. So why is there any need for a more complicated Registry mechanism?
I also don't see any need for an id field within a Converter.

- Josef
Post Reply