[interfacekit] Phase 1
- From: "Ingo Weinhold" <bonefish@xxxxxxxxxxxxxxx>
- To: "Interface Kit List" <interfacekit@xxxxxxxxxxxxx>
- Date: Wed, 03 Jul 2002 01:43:38 CEST (+0200)
Hi,
well, it looks like I can't stop sending longish mails. ;-)
CU, Ingo
Tasks
-----
This is basically a reincarnation of the feature list I sent earlier.
Closely related items are bundled into work packages. Though it might
work out well, if two guys work on a package at the same time, it is
probably simpler, if a package is dealt with by one person only.
1. BMessenger, save the signature constructor
(LockTarget*() shouldn't be needed either, they might be easy to
implement implement though)
2. registrar/roster embryo
- make BApplication registrar-aware, i.e. name the looper port
respectively
- registrar skeleton
- BRoster constructor/initialization
3. app registration
- roster side registration support
- roster side running app management
- private BRoster app registration methods
- basic BApplication signature constructors/BApplication::InitData()
- BApplication::Argv/RefsReceived(), ReadyToRun(), Quit[Requested]()
4. running app querying, BMessenger
- running application querying (roster/BRoster)
- BMessenger: signature constructor
- BRoster::ActivateApp()
Unfortunately the order is relatively strict: 3. requires 1. and 2.,
and 4. builds on top of 3.
1. and 2. can be done mostly in parallel, though at the end of 2.
BMessenger will ne needed. I have no idea how well the libbe BMessenger
deals with our BHandler/BLooper objects though.
Tests
-----
Usually I prefer to write the tests before the implementation, but I
would relax the rule a bit. Writing the BMessenger tests first for
instance would hold all other packages. Thus I think, it is reasonable
to write the tests for a package after implementing it.
Originally I intended to list some test ideas for each packages, but
it's actually straight forward: All the features implemented by a
package need to be tested. ;-)
Conventions
-----------
A subject with a lot of potential for discussions. ;-)
I just want to propose something and, if you find it reasonable, then
we go with it, otherwise make a proposal yourself.
First of all, the registrar is an application on its own and none of
its code lives in libbe or appears in any of the public headers (one
exception: _TRoster_ -- see below), so there is no reason to name
classes BXyz and constants B_XYZ. The constants are used in the API
classes implementations and therefore I suggest the common prefix REG_.
The classes on the other hand don't need a prefix and thus I wouldn't
prepend any.
For the message constant values I suggest four small letters starting
with 'rg', e.g. 'rgsu' for REG_SUCCESS. The same convention goes for
type constants. Note, that neither the message nor the type constants
will ever get in touch with user application entities. Messages with a
registrar specific "what" field or one containing a specifically typed
field are only allowed for messages sent to the registrar and for
synchronous reply messages to those. Such a message must never be sent
to an application or any handler.
Error constants start at B_ERRORS_END + 1.
To not interfere with the BeOS registrar I propose the names
"_obos_roster_thread_" and "_obos_roster_port_" for the registrar's
main thread and app looper port respectively. The names should be
defined as static variables in a common header file (Registrar.h). The
other shared definitions should be located there as well.
Structures/Classes
------------------
The only more or less interesting structures/classes are those in the
roster, namely _TRoster_ (a friend of BMessenger), which manages the
running applications. First of all, please let us rename that beast.
Let's move it into the BPrivate namespace and call it just Roster (or
TRoster, though I'm not sure what the T stands for -- team maybe?).
The basic information to be stored for each application is an app_info.
Since we need additional data to be associated with an application, we
probably want to wrap it like this:
struct RosterAppInfo : public app_info {
uint32 state;
int32 argc;
char **argv;
int32 ref_count;
entry_ref **refs;
int32 message_count;
BMessage *messages;
[...helper methods...]
};
state can be something like REG_APP_REGISTERED or REG_APP_RUNNING.
argc and argv are only needed in the registration phase, until the
application's Run() is called and the B_ARGV_RECEIVED has been sent.
The same goes for ref_count, refs, message_count and messages, which we
won't need until we are going to implement the respective versions of
BRoster::Launch().
Roster must implement an efficient team_id->RosterAppInfo and signature
->set of RosterAppInfo mapping. As the number of applications will
quite likely be relatively small (< 100), even a single unsorted list
and a linear search should be sufficient. We may want to consider
binary search on sorted lists or even hash tables later.
The Roster class will implement all roster features. The registrar
application's MessageReceived() may dispatch the roster messages
directly to the respective Roster methods. It might not even extract
the contents of the message, but rather leave that for Roster.
Implementation
--------------
No, don't expect to find the complete implementation in this section.
;-)
Just a short implementation remark concerning the app registration.
Until this time I don't see the need for all the private BRoster
registration related methods. I would keep only four of them and change
there semantics a bit:
status_t RegisterApp(const char *signature, const entry_ref *ref
uint32 flags, team_id team, port_id
port,
int32 argc, const char *const *argv)
Registers the application with the roster. Called from the BApplication
constructor. It fails when the application is single/exclusive launch
and an instance of it is already running. The supplied command line
arguments are sent (by the roster) as a B_ARGV_RECEIVED message to the
respective team in this case.
params:
- signature: The application signature.
- ref: An entry_ref to the application executable.
- flags: The application flags.
- team: The application team.
- port: The app looper port.
- argc: The application's command line parameter count.
- argv: The application's command line parameters.
return:
- B_OK: :-))
- B_BAD_VALUE: Invalid parameter value.
- REG_ALREADY_REGISTERED: For single/exclusive launch applications
that are launched the second time.
- ...
-----------------------------------------------------------------------
status_t RegisterRunningApp(team_id team, thread_id thread)
Tells the roster, that the application is now going to run the message
loop. The roster sends the command line arguments as a B_ARGV_RECEIVED
message and if applicable also a B_REFS_RECEIVED and other initial
messages and finally a B_READY_TO_RUN.
params:
- team: The application team.
- thread: The application looper thread.
return:
- B_OK: :-))
- ...
-----------------------------------------------------------------------
status_t UnregisterRunningApp(team_id team)
Tells the roster, that the application is going to stop the message
loop.
params:
- team: The application team.
return:
- B_OK: :-))
- ...
-----------------------------------------------------------------------
status_t UnregisterApp(team_id team)
Unregisters the application from the roster. Called from the
BApplication destructor.
params:
- team: The application team.
return:
- B_OK: :-))
- ...
Protocols
---------
standard success reply message
reply: - REG_SUCCESS
[ <additional fields> ]
fields:
- <additional fields>: Request-specific fields.
-----------------------------------------------------------------------
standard error reply message
reply: - REG_ERROR
"error": B_INT32_TYPE
[ "error_description": B_STRING_TYPE ]
[ <additional fields> ]
fields:
- "error": The error code (a status_t).
- "error_description": Optional human readable description.
- <additional fields>: Request-specific fields.
-----------------------------------------------------------------------
(package 2)
getting the messengers for MIME and clipboard management respectively
target: registrar app looper (preferred handler)
message: REG_GET_MIME_MESSENGER/REG_GET_CLIPBOARD_MESSENGER
reply: standard success
"messenger": B_MESSENGER_TYPE
on error: - B_NO_REPLY (fatal)
- standard error (fatal)
reply fields:
- "messenger": The requested messenger.
-----------------------------------------------------------------------
(package 3)
app registration (BRoster::RegisterApp())
target: roster
message: REG_REGISTER_APP
"signature": B_MIME_STRING_TYPE
"ref": B_REF_TYPE
"flags": B_UINT32_TYPE
"team": B_INT32_TYPE
"port": B_INT32_TYPE
"argv": B_STRING_TYPE[]
reply: standard success
on error: - B_NO_REPLY (fatal)
- standard error
message fields:
- "signature": The application signature.
- "ref": An entry_ref to the application executable.
- "flags": The application flags.
- "team": The application team (team_id).
- "port": The app looper port (port_id).
- "argv": The application's command line parameters.
error reply fields:
- "error":
- B_BAD_VALUE: A request message field is missing or contains an
invalid value.
- REG_ALREADY_REGISTERED: For single/exclusive launch applications
that are launched the second time.
- ...
-----------------------------------------------------------------------
app registration (BRoster::RegisterRunningApp())
target: roster
message: REG_REGISTER_RUNNING_APP
"team": B_INT32_TYPE
"thread": B_INT32_TYPE
reply: standard success
on error: - B_NO_REPLY (fatal)
- standard error (fatal)
message fields:
- "team": The application team (team_id).
- "thread": The application looper thread (thread_id).
-----------------------------------------------------------------------
app unregistration (BRoster::UnregisterRunningApp())
target: roster
message: REG_UNREGISTER_RUNNING_APP
"team": B_INT32_TYPE
reply: standard success
on error: - B_NO_REPLY (fatal)
- standard error (fatal)
message fields:
- "team": The application team (team_id).
-----------------------------------------------------------------------
app unregistration (BRoster::UnregisterApp())
target: roster
message: REG_UNREGISTER_APP
"team": B_INT32_TYPE
reply: standard success
on error: - B_NO_REPLY (fatal)
- standard error (fatal)
message fields:
- "team": The application team (team_id).
-----------------------------------------------------------------------
(package 4)
getting a running app list (BRoster::GetAppList())
target: roster
message: REG_GET_APP_LIST
[ "signature": B_MIME_STRING_TYPE ]
reply: standard success
[ "teams": B_INT32_TYPE[] ]
on error: - B_NO_REPLY (fatal)
- standard error (fatal)
message fields:
- "signature": The signature of the running applications to be listed.
All running applications, if omitted.
reply fields:
- "teams": The team IDs of the applications found (team_id). Omitted,
if no application could be found.
-----------------------------------------------------------------------
getting a running app info (BRoster::GetRunningAppInfo(),
BRoster::GetActiveAppInfo())
target: roster
message: REG_GET_RUNNING_APP_INFO
[ "team": B_INT32_TYPE ]
reply: standard success
"info": REG_APP_INFO_TYPE
on error: - B_NO_REPLY (fatal)
- standard error
message fields:
- "team": The team ID of the application in question (team_id).
If omitted, the active application is considered.
reply fields:
- "info": An app_info structure containing the requested info.
error reply fields:
- "error":
- B_BAD_TEAM_ID: No team with the supplied ID exists.
- B_ENTRY_NOT_FOUND: The supplied team ID does not identify an
application (the team exists though), or currently there is no
active application.
- ...
-----------------------------------------------------------------------
app activation (BRoster::ActivateApp())
target: roster
message: REG_ACTIVATE_APP
"team": B_INT32_TYPE
reply: standard success
on error: - B_NO_REPLY (fatal)
- standard error
message fields:
- "team": The team ID of the application to be activated.
error reply fields:
- "error":
- B_BAD_TEAM_ID: No team with the supplied ID exists.
- B_ENTRY_NOT_FOUND: The supplied team ID does not identify an
application (the team exists though).
- ...
- Follow-Ups:
- [interfacekit] Re: Phase 1
- From: Cedric Degea
Other related posts:
- [interfacekit] Re: Phase 1
- From: Cedric Degea