<?xml version="1.0"?>
<?xml-stylesheet type="text/css" href="http://stlab.adobe.com/wiki/skins/common/feed.css?303"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
		<id>http://stlab.adobe.com/wiki/index.php?title=Deferred_Procedure_Call_System&amp;feed=atom&amp;action=history</id>
		<title>Deferred Procedure Call System - Revision history</title>
		<link rel="self" type="application/atom+xml" href="http://stlab.adobe.com/wiki/index.php?title=Deferred_Procedure_Call_System&amp;feed=atom&amp;action=history"/>
		<link rel="alternate" type="text/html" href="http://stlab.adobe.com/wiki/index.php?title=Deferred_Procedure_Call_System&amp;action=history"/>
		<updated>2013-05-19T02:16:57Z</updated>
		<subtitle>Revision history for this page on the wiki</subtitle>
		<generator>MediaWiki 1.19.0</generator>

	<entry>
		<id>http://stlab.adobe.com/wiki/index.php?title=Deferred_Procedure_Call_System&amp;diff=1433&amp;oldid=prev</id>
		<title>FosterBrereton: initial population</title>
		<link rel="alternate" type="text/html" href="http://stlab.adobe.com/wiki/index.php?title=Deferred_Procedure_Call_System&amp;diff=1433&amp;oldid=prev"/>
				<updated>2006-06-21T19:29:32Z</updated>
		
		<summary type="html">&lt;p&gt;initial population&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;==Overview==&lt;br /&gt;
&lt;br /&gt;
The DPCS is intended to queue up routine calls for execution at a later point in time. Such instances where this might be useful would be:&lt;br /&gt;
* Performing a task at a later time (preferrably at the unwinding of the call stack)&lt;br /&gt;
* &amp;quot;Throwing&amp;quot; errors across DLL boundaries&lt;br /&gt;
* Collecting various events for a set of windows (e.g., redraw or update events) then executing all the events for all the windows at a single time&lt;br /&gt;
&lt;br /&gt;
==Terminology==&lt;br /&gt;
&lt;br /&gt;
; verb : A singleton procedure that is called at a later date.&lt;br /&gt;
; verb_queue : A collection of verbs.&lt;br /&gt;
; behavior:  A collection of verbs, verb queues, and other behaviors (subbehaviors). As verbs, verb queues, and subbehaviors are inserted into a behavior, the order in which they were inserted is retained, and becomes the order in which the behavior executes inserted children.&lt;br /&gt;
&lt;br /&gt;
==API==&lt;br /&gt;
&lt;br /&gt;
The current proposed API is as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
typedef boost::function&amp;lt;void ()&amp;gt; verb_t;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* A &amp;lt;code&amp;gt;verb_t&amp;lt;/code&amp;gt; is a self-contained callback proc that is executed at a specific time&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
typedef struct verb_queue_t* verb_q_token_t;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* A &amp;lt;code&amp;gt;verb_queue_t&amp;lt;/code&amp;gt; is a collection of verbs&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
typedef struct behavior_t* behavior_token_t;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* A &amp;lt;code&amp;gt;behavior_token_t&amp;lt;/code&amp;gt; is a collection of verbs, verb queues, and other behaviors (subbehaviors)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
behavior_token_t make_behavior();&lt;br /&gt;
void destroy_behavior(behavior_token_t behavior);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;make_behavior&amp;lt;/code&amp;gt; allocates a new behavior and returns the token to the client. The client is responsible for destroying the behavior with:&lt;br /&gt;
* &amp;lt;code&amp;gt;destroy_behavior&amp;lt;/code&amp;gt; destroys memory allocated for the the behavior. If the behavior is a subbehavior within another behavior, it is detached from its parent behavior. Likewise if the behavior being destructed contains any subbehaviors, they are destroyed as well.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void insert(behavior_token_t behavior, verb_t verb, bool single_execution);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* This version of &amp;lt;code&amp;gt;insert&amp;lt;/code&amp;gt; will add a single verb at this current point in the behavior. if &amp;lt;code&amp;gt;single_execution&amp;lt;/code&amp;gt; is true then the verb will be destroyed after the first time it is executed.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
behavior_token_t insert_behavior(behavior_token_t behavior);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;insert_behavior&amp;lt;/code&amp;gt; adds a subbehavior at this current point in the behavior. The function returns to the client the &amp;lt;code&amp;gt;behavior_token_t&amp;lt;/code&amp;gt; of the newly created subbehavior. You are &amp;lt;i&amp;gt;not&amp;lt;/i&amp;gt; responsible for destroying the subbehavior, though you may if you choose to do so (detaching it from the parent behavior).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
verb_q_token_t insert_queue(behavior_token_t behavior, bool single_execution);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;insert_queue&amp;lt;/code&amp;gt; adds a verb queue at this current point in the behavior. The function returns to the client the &amp;lt;code&amp;gt;verb_q_token_t&amp;lt;/code&amp;gt; of the newly created verb queue. You are not allowed to destroy verb queues. If &amp;lt;code&amp;gt;single_execution&amp;lt;/code&amp;gt; is set to true, every verb in the queue will be destroyed after the first time it is. However, the verb queue itself will &amp;lt;i&amp;gt;not&amp;lt;/i&amp;gt; be destroyed, allowing for further verb insertion at a later point into the same queue.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
bool empty(behavior_token_t behavior);&lt;br /&gt;
std::size_t size(behavior_token_t behavior);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;empty&amp;lt;/code&amp;gt; returns to the client whether or not the behavior is empty.&lt;br /&gt;
* &amp;lt;code&amp;gt;size&amp;lt;/code&amp;gt; returns the number of singleton verbs, verb queues, and subbehaviors that have been inserted into this behavior.&lt;br /&gt;
   &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void execute(behavior_token_t behavior);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;execute&amp;lt;/code&amp;gt; will iterate through the children of this behavior and execute them in the order in which they were inserted. Note that this ordering is &amp;quot;one level deep&amp;quot; -- inserting a verb into a verb_queue that was inserted first into this behavior will result in that verb executing before any of the other immediate children of this behavior. If any verbs are marked as &amp;lt;code&amp;gt;single_execution&amp;lt;/code&amp;gt;, they will not exist before this call is complete. Likewise, any verb queues marked &amp;lt;code&amp;gt;single_execution&amp;lt;/code&amp;gt; will be empty before the completion of this function call.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void insert(verb_q_token_t verb_q, verb_t verb);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* This version of &amp;lt;code&amp;gt;insert&amp;lt;/code&amp;gt; will append a verb to the end of this verb queue.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
bool empty(verb_q_token_t verb_q);&lt;br /&gt;
std::size_t size(verb_q_token_t verb_q);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;empty&amp;lt;/code&amp;gt; returns to the client whether or not the verb queue is empty.&lt;br /&gt;
* &amp;lt;code&amp;gt;size&amp;lt;/code&amp;gt; returns the number of singleton verbs that have been inserted into this verb queue.&lt;br /&gt;
   &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void execute(verb_q_token_t verb_q);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;execute&amp;lt;/code&amp;gt; will iterate through the verbs of this verb queue and execute them in the order in which they were inserted into this queue. If this verb queue was marked &amp;lt;code&amp;gt;single_execution&amp;lt;/code&amp;gt; it will be empty before the completion of this function call.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
template&amp;lt;&amp;gt;&lt;br /&gt;
struct delete_ptr&amp;lt;behavior_token_t&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
    typedef void result_type;&lt;br /&gt;
&lt;br /&gt;
    void operator()(behavior_token_t x) const&lt;br /&gt;
        { if (x) destroy_behavior(x); }&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* This template specialization is intended for use with the &amp;lt;code&amp;gt;adobe::auto_resource&amp;lt;/code&amp;gt; class.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
verb_q_token_t general_deferred_proc_queue();&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* The general deferred proc queue is a catchall verb queue for verbs that need to be executed at the end of this iteration through the application's event loop. It is constructed as a &amp;lt;code&amp;gt;single_execution&amp;lt;/code&amp;gt; verb queue. The application binary is required to execute this verb queue at the end of every iteration of its event loop.&lt;br /&gt;
&lt;br /&gt;
==Issues==&lt;br /&gt;
&lt;br /&gt;
* There is a need for better locality - these are all things that have to happen after something else - the problem is the &amp;quot;something else&amp;quot; should not be known locally to the code doing the queuing.&lt;br /&gt;
* The basic need is for an explicit set of connections made by whatever code is connecting things up&lt;/div&gt;</summary>
		<author><name>FosterBrereton</name></author>	</entry>

	</feed>