[Date Prev][Date Next][Thread Prev][Thread Next][Author Index][Date Index][Thread Index]

Re: stubble message continued....



> From: tribble (Eric Dean Tribble)

> sendSelfTo: remains as the message to send the state of the object.  A
> new message like 'sendOn:' would have a default implementation in
> heaper that sends sends the category, the open parenthesis, calls
> sendSelfTo:, then sends the close parenthesis.  We may want to have a
> special version of this for sending proxies as opposed to sending to
> the disk, but we could also have special distinction made on the type
> of the transceiver.
> 
> How does this fit with the recent changes in design?  Does this break
> anything?  Alternatives?

That is something like the first cut.

Here's the sending side of what we have now, per markm's letter recording
the contents of the first session, with one revision from the second
session, one lost line installed, and the classname corrected.  Most of
the change is to the heaper send method of the Xcvr.

================ sending side ===========================================

void TextyCommXcvr::
send(Heaper * obj)
{
   SPTR(Heaper) sobj;
   IntegerVar objNum;

   if (sobj = this->fetchEntryFor(obj)) {	// copy or proxy already there:
      this->send(obj);				// send the table entry

   } else if (obj->isByProxy()) {		// New by-proxy object:
      objNum = myCommHandler->assignNumberFor(obj);	// Make entry
      this->startInstance(obj->getProxyCategory());	// send "Foo_proxy("
							// (comHandler is known)
      this->send(objNum);				// send object number.
      obj->sendProxyTo(this);				// send any copy guts
      this->endInstance();				// send ")"

   } else {					// by-copy object:
      this->assignNumberFor(obj);		// break cycles
      this->startInstance(obj->getCategory());	// send "Foo("
      obj->sendSelfTo(this);			// send guts
      this->endInstance();			// send ")"
   }
}

Corresponding changes elsewhere:

 - Objects have new methods:

    - "isByProxy()"		Returns TRUE if the object is sent by proxy.

    - "getProxyCategory()"	Returns the category object of the object's
				>proxy<'s class.

    - "sendProxyTo(CommXcvr *)"	Sends the copy part of mixed by-copy/by-proxy
				objects.  (This does nothing on pure by-proxies)

 - Xcvrs have new methods:

    - assignNumberFor(Heaper *)	Breaks cycles and interns copy objects within
				a transmission (so they're only sent once), by
				maintaining a per-Xcvr table similar to the one
				in CommHandlers.

    - fetchEntryFor(Heaper *)	Searches the Xcvr's table for the Entry, then
				sends entryFor() to the CommHandler if the
				entry is not found in the Xcvr's table.

Typical sendProxyTo() for copy part of a mixed copy/proxy object
(say, a by-proxy class built on a by-copy base class):

void Foo::
sendProxyTo(CommXcvr * trans)
{
   this->Foo::sendSelfTo(trans);
}

(I think the mixed copy/proxy stuff needs more work.  Perhaps that should
 be something like "sendCopyPartTo(trans)"?)

=======================================================================

Here's the receiving side, per wjr's recording of the second session:

=======================================================================

TextyCommXcvr::
receive (Category * catObject)
{
    /* declarations ... */

    getIdentifier (receivedBuffer, className, MAX...);

    if (strcmp (className, "NULL") == 0){ // NULLs are easy
	return NULL;

    } else {				// What have we got?
      recipe = getRecipe (className);
      getCharToken (receivedBuffer, '('));

      switch (recipe->kindOfRecipe()) {

      case ENTRY_KIND:			// Some kind of entry:
        entry = NULL;			// (Not used, but init it anyhow)
        break;

      case PROXY_KIND:			// Some kind of proxy:
        this->receive(cat_IntegerVar, sizeof objNum, &objNum);	// Get entry #
        entry = commHandler->addEntry(objNum);	// already know the commHandler
        break;

      case COPY_KIND:			// Pure copy object.
        entry = this->addEntry();	// Keep cycle-breaker in sync.
        break;

      }

      result = recipe->make(this, entry);	// Make one of it.
						// It will fill in the Entry

      getCharToken (receivedBuffer, ')');	// Eat the ")"

      if (!result->isKindOf (catObject){	// Be sure it's what we want
        BLAST(...);
      }

    }
    return result;
}

Corresponding changes:

 - Recipes have a new subclass: "ProxyRecipe".  Recipes for proxy
   objects inherit from it, rather than directly from Recipe.
   It exists only to override one method.

 - Recipes have a new method:  kindOfRecipe().  It returns an enum
   describing which sort of object the recipe will build.  It is
   defined to return "COPY_KIND" in Recipe, and overridden in ProxyRecipe
   and by the entry recipes.

 - The Recipe::make() method is overloaded.
    - Heaper Recipes only need to define make(Xcvr *, Entry *).
    - Var Recipes only need to define make(Xcvr *, OUT IntegerVar *).

 - Entries are created with the pointer initially NULL, and passed to
   Recipe::make().  Once the object has storage, it fills in the pointer
   in the Entry.

 - Cycles are broken (and copy classes within one Xcvr::send(Heaper *)
   interned) by a table of the new EntryXcvr subclass of Entry, held
   by the Xcvr.  (On the sending side, this table is searched first,
   and the Handler's table searched if no hit is found.)
   New method:  Xcvr::addEntry()

 - Of course, there are a number of changes to StubbleForm.f to
   support all this.

	michael