plug char leak

This commit is contained in:
David Rose 2002-01-31 19:08:07 +00:00
parent c402611a7f
commit b5f89092bb
7 changed files with 65 additions and 56 deletions

View File

@ -21,7 +21,7 @@
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: AnimControl::set_play_rate // Function: AnimControl::set_play_rate
// Access: Public // Access: Published
// Description: Sets the speed of the animation, relative to its // Description: Sets the speed of the animation, relative to its
// "normal" speed. Setting this number to 2.0 plays it // "normal" speed. Setting this number to 2.0 plays it
// twice as fast, 0.5 half as fast. -1.0 plays it // twice as fast, 0.5 half as fast. -1.0 plays it
@ -42,7 +42,7 @@ set_play_rate(double play_rate) {
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: AnimControl::get_play_rate // Function: AnimControl::get_play_rate
// Access: Public // Access: Published
// Description: Returns the current speed of the animation. See // Description: Returns the current speed of the animation. See
// set_play_rate(). // set_play_rate().
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
@ -53,7 +53,7 @@ get_play_rate() const {
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: AnimControl::get_frame_rate // Function: AnimControl::get_frame_rate
// Access: Public // Access: Published
// Description: Returns the actual frame rate of the animation, based // Description: Returns the actual frame rate of the animation, based
// on the play_rate (see set_play_rate()) and the // on the play_rate (see set_play_rate()) and the
// animation's base frame rate (see // animation's base frame rate (see
@ -67,7 +67,7 @@ get_frame_rate() const {
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: AnimControl::get_frame // Function: AnimControl::get_frame
// Access: Public // Access: Published
// Description: Returns the current frame number of the animation. // Description: Returns the current frame number of the animation.
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
INLINE int AnimControl:: INLINE int AnimControl::
@ -80,7 +80,7 @@ get_frame() const {
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: AnimControl::get_num_frames // Function: AnimControl::get_num_frames
// Access: Public // Access: Published
// Description: Returns the number of frames of animation. This is // Description: Returns the number of frames of animation. This is
// actually just extracted directly from the AnimBundle; // actually just extracted directly from the AnimBundle;
// the function is duplicated here for convenience. The // the function is duplicated here for convenience. The
@ -94,7 +94,7 @@ get_num_frames() const {
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: AnimControl::is_playing // Function: AnimControl::is_playing
// Access: Public // Access: Published
// Description: Returns true if the AnimControl is currently playing, // Description: Returns true if the AnimControl is currently playing,
// false otherwise. // false otherwise.
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
@ -105,7 +105,7 @@ is_playing() const {
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: AnimControl::get_anim // Function: AnimControl::get_anim
// Access: Public // Access: Published
// Description: Returns the AnimBundle bound in with this // Description: Returns the AnimBundle bound in with this
// AnimControl. // AnimControl.
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////

View File

@ -30,7 +30,7 @@ TypeHandle AnimControl::_type_handle;
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: AnimControl::Constructor // Function: AnimControl::Constructor
// Access: Public, Scheme // Access: Public
// Description: // Description:
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
AnimControl:: AnimControl::
@ -49,10 +49,20 @@ AnimControl(PartBundle *part, AnimBundle *anim, int channel_index) {
_marked_frame = -1; _marked_frame = -1;
} }
////////////////////////////////////////////////////////////////////
// Function: AnimControl::Destructor
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
AnimControl::
~AnimControl() {
get_part()->set_control_effect(this, 0.0f);
}
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: AnimControl::play // Function: AnimControl::play
// Access: Public // Access: Published
// Description: Runs the entire animation from beginning to end and // Description: Runs the entire animation from beginning to end and
// stops, throwing the stop event (if it is non-NULL). // stops, throwing the stop event (if it is non-NULL).
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
@ -69,7 +79,7 @@ play(const CPT_Event &stop_event) {
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: AnimControl::play // Function: AnimControl::play
// Access: Public // Access: Published
// Description: Runs the animation from the frame "from" to and // Description: Runs the animation from the frame "from" to and
// including the frame "to", at which point the // including the frame "to", at which point the
// animation is stopped and the indicated stop event is // animation is stopped and the indicated stop event is
@ -99,7 +109,7 @@ play(int from, int to, const CPT_Event &stop_event) {
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: AnimControl::loop // Function: AnimControl::loop
// Access: Public // Access: Published
// Description: Starts the entire animation looping. If restart is // Description: Starts the entire animation looping. If restart is
// true, the animation is restarted from the beginning; // true, the animation is restarted from the beginning;
// otherwise, it continues from the current frame. // otherwise, it continues from the current frame.
@ -125,7 +135,7 @@ loop(bool restart) {
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: AnimControl::loop // Function: AnimControl::loop
// Access: Public // Access: Published
// Description: Loops the animation from the frame "from" to and // Description: Loops the animation from the frame "from" to and
// including the frame "to", indefinitely. If restart // including the frame "to", indefinitely. If restart
// is true, the animation is restarted from the // is true, the animation is restarted from the
@ -192,7 +202,7 @@ loop(bool restart, int from, int to) {
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: AnimControl::pingpong // Function: AnimControl::pingpong
// Access: Public // Access: Published
// Description: Loops the animation from the frame "from" to and // Description: Loops the animation from the frame "from" to and
// including the frame "to", and then back in the // including the frame "to", and then back in the
// opposite direction, indefinitely. // opposite direction, indefinitely.
@ -224,7 +234,7 @@ pingpong(bool restart, int from, int to) {
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: AnimControl::stop // Function: AnimControl::stop
// Access: Public // Access: Published
// Description: Stops a currently playing or looping animation right // Description: Stops a currently playing or looping animation right
// where it is. The animation remains posed at the // where it is. The animation remains posed at the
// current frame, and no event is thrown. // current frame, and no event is thrown.
@ -236,7 +246,7 @@ stop() {
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: AnimControl::pose // Function: AnimControl::pose
// Access: Public // Access: Published
// Description: Sets the animation to the indicated frame and holds // Description: Sets the animation to the indicated frame and holds
// it there. // it there.
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
@ -257,7 +267,7 @@ pose(int frame) {
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: AnimControl::add_event // Function: AnimControl::add_event
// Access: Public // Access: Published
// Description: Adds the indicated event to the list of events that // Description: Adds the indicated event to the list of events that
// will be called whenever the animation reaches the // will be called whenever the animation reaches the
// indicated frame number. Once added, the event will // indicated frame number. Once added, the event will
@ -274,7 +284,7 @@ add_event(int frame, const CPT_Event &event) {
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: AnimControl::remove_event // Function: AnimControl::remove_event
// Access: Public // Access: Published
// Description: Removes all events found that match the indicated // Description: Removes all events found that match the indicated
// event name, and returns the number of events // event name, and returns the number of events
// removed. // removed.
@ -325,7 +335,7 @@ remove_event(const string &event_name) {
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: AnimControl::remove_all_events // Function: AnimControl::remove_all_events
// Access: Public // Access: Published
// Description: Removes all user-defined event messages. However, if // Description: Removes all user-defined event messages. However, if
// called while an animation is running, this will not // called while an animation is running, this will not
// take effect until the animation is stopped and // take effect until the animation is stopped and
@ -338,7 +348,7 @@ remove_all_events() {
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: AnimControl::get_part // Function: AnimControl::get_part
// Access: Public // Access: Published
// Description: Returns the PartBundle bound in with this // Description: Returns the PartBundle bound in with this
// AnimControl. // AnimControl.
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////

View File

@ -49,6 +49,7 @@ public:
AnimControl(PartBundle *part, AnimBundle *anim, int channel_index); AnimControl(PartBundle *part, AnimBundle *anim, int channel_index);
PUBLISHED: PUBLISHED:
~AnimControl();
void play(const CPT_Event &stop_event = NULL); void play(const CPT_Event &stop_event = NULL);
void play(int from, int to, const CPT_Event &stop_event = NULL); void play(int from, int to, const CPT_Event &stop_event = NULL);
void loop(bool restart); void loop(bool restart);

View File

@ -22,7 +22,7 @@
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: AnimControlCollection::Constructor // Function: AnimControlCollection::Constructor
// Access: Public // Access: Published
// Description: Returns the AnimControl associated with the given // Description: Returns the AnimControl associated with the given
// name, or NULL if no such control has been associated. // name, or NULL if no such control has been associated.
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
@ -33,7 +33,7 @@ AnimControlCollection() {
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: AnimControlCollection::Destructor // Function: AnimControlCollection::Destructor
// Access: Public // Access: Published
// Description: // Description:
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
AnimControlCollection:: AnimControlCollection::
@ -42,7 +42,7 @@ AnimControlCollection::
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: AnimControlCollection::store_anim // Function: AnimControlCollection::store_anim
// Access: Public // Access: Published
// Description: Associates the given AnimControl with this collection // Description: Associates the given AnimControl with this collection
// under the given name. The AnimControl will remain // under the given name. The AnimControl will remain
// associated until a new AnimControl is associated with // associated until a new AnimControl is associated with
@ -64,7 +64,7 @@ store_anim(AnimControl *control, const string &name) {
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: AnimControlCollection::find_anim // Function: AnimControlCollection::find_anim
// Access: Public // Access: Published
// Description: Returns the AnimControl associated with the given // Description: Returns the AnimControl associated with the given
// name, or NULL if no such control has been associated. // name, or NULL if no such control has been associated.
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
@ -79,7 +79,7 @@ find_anim(const string &name) const {
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: AnimControlCollection::unbind_anim // Function: AnimControlCollection::unbind_anim
// Access: Public // Access: Published
// Description: Removes the AnimControl associated with the given // Description: Removes the AnimControl associated with the given
// name, if any. Returns true if an AnimControl was // name, if any. Returns true if an AnimControl was
// removed, false if there was no AnimControl with the // removed, false if there was no AnimControl with the
@ -100,7 +100,7 @@ unbind_anim(const string &name) {
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: AnimControlCollection::get_num_anims // Function: AnimControlCollection::get_num_anims
// Access: Public // Access: Published
// Description: Returns the number of AnimControls associated with // Description: Returns the number of AnimControls associated with
// this collection. // this collection.
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
@ -111,7 +111,7 @@ get_num_anims() const {
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: AnimControlCollection::clear_anims // Function: AnimControlCollection::clear_anims
// Access: Public // Access: Published
// Description: Disassociates all anims from this collection. // Description: Disassociates all anims from this collection.
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
void AnimControlCollection:: void AnimControlCollection::
@ -121,7 +121,7 @@ clear_anims() {
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: AnimControlCollection::play_all // Function: AnimControlCollection::play_all
// Access: Public // Access: Published
// Description: Starts all animations playing. // Description: Starts all animations playing.
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
void AnimControlCollection:: void AnimControlCollection::
@ -134,7 +134,7 @@ play_all() {
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: AnimControlCollection::play_all // Function: AnimControlCollection::play_all
// Access: Public // Access: Published
// Description: Starts all animations playing. // Description: Starts all animations playing.
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
void AnimControlCollection:: void AnimControlCollection::
@ -147,7 +147,7 @@ play_all(int from, int to) {
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: AnimControlCollection::loop_all // Function: AnimControlCollection::loop_all
// Access: Public // Access: Published
// Description: Starts all animations looping. // Description: Starts all animations looping.
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
void AnimControlCollection:: void AnimControlCollection::
@ -160,7 +160,7 @@ loop_all(bool restart) {
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: AnimControlCollection::loop_all // Function: AnimControlCollection::loop_all
// Access: Public // Access: Published
// Description: Starts all animations looping. // Description: Starts all animations looping.
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
void AnimControlCollection:: void AnimControlCollection::
@ -173,7 +173,7 @@ loop_all(bool restart, int from, int to) {
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: AnimControlCollection::stop_all // Function: AnimControlCollection::stop_all
// Access: Public // Access: Published
// Description: Stops all currently playing animations. Returns true // Description: Stops all currently playing animations. Returns true
// if any animations were stopped, false if none were // if any animations were stopped, false if none were
// playing. // playing.
@ -194,7 +194,7 @@ stop_all() {
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: AnimControlCollection::pose_all // Function: AnimControlCollection::pose_all
// Access: Public // Access: Published
// Description: Sets all animations to the indicated frame. // Description: Sets all animations to the indicated frame.
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
void AnimControlCollection:: void AnimControlCollection::
@ -207,7 +207,7 @@ pose_all(int frame) {
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: AnimControlCollection::which_anim_playing // Function: AnimControlCollection::which_anim_playing
// Access: Public // Access: Published
// Description: Returns the name of the bound AnimControl currently // Description: Returns the name of the bound AnimControl currently
// playing, if any. If more than one AnimControl is // playing, if any. If more than one AnimControl is
// currently playing, returns all of the names separated // currently playing, returns all of the names separated

View File

@ -19,7 +19,7 @@
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: PartBundle::get_blend_type // Function: PartBundle::get_blend_type
// Access: Public // Access: Published
// Description: Returns the way the character responds to multiple // Description: Returns the way the character responds to multiple
// animations being bound simultaneously. // animations being bound simultaneously.
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
@ -30,7 +30,7 @@ get_blend_type() const {
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: PartBundle::get_node // Function: PartBundle::get_node
// Access: Public // Access: Published
// Description: Returns the PartBundleNode associated with this // Description: Returns the PartBundleNode associated with this
// PartBundle. // PartBundle.
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////

View File

@ -80,7 +80,7 @@ make_copy() const {
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: PartBundle::set_blend_type // Function: PartBundle::set_blend_type
// Access: Public // Access: Published
// Description: Defines the way the character responds to multiple // Description: Defines the way the character responds to multiple
// set_control_effect()). By default, the blend_type is // set_control_effect()). By default, the blend_type is
// BT_single, which disallows multiple animations. In // BT_single, which disallows multiple animations. In
@ -118,7 +118,7 @@ set_blend_type(BlendType bt) {
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: PartBundle::clear_control_effects // Function: PartBundle::clear_control_effects
// Access: Public // Access: Published
// Description: Sets the control effect of all AnimControls to zero // Description: Sets the control effect of all AnimControls to zero
// (but does not "stop" the AnimControls). The // (but does not "stop" the AnimControls). The
// character will no longer be affected by any // character will no longer be affected by any
@ -143,7 +143,7 @@ clear_control_effects() {
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: PartBundle::set_control_effect // Function: PartBundle::set_control_effect
// Access: Public // Access: Published
// Description: Sets the amount by which the character is affected by // Description: Sets the amount by which the character is affected by
// the indicated AnimControl (and its associated // the indicated AnimControl (and its associated
// animation). Normally, this will only be zero or one. // animation). Normally, this will only be zero or one.
@ -191,7 +191,7 @@ set_control_effect(AnimControl *control, float effect) {
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: PartBundle::get_control_effect // Function: PartBundle::get_control_effect
// Access: Public // Access: Published
// Description: Returns the amount by which the character is affected // Description: Returns the amount by which the character is affected
// by the indicated AnimControl and its associated // by the indicated AnimControl and its associated
// animation. See set_control_effect(). // animation. See set_control_effect().
@ -213,7 +213,7 @@ get_control_effect(AnimControl *control) {
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: PartBundle::output // Function: PartBundle::output
// Access: Public, Virtual // Access: Published, Virtual
// Description: Writes a one-line description of the bundle. // Description: Writes a one-line description of the bundle.
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
void PartBundle:: void PartBundle::
@ -223,7 +223,7 @@ output(ostream &out) const {
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: PartBundle::write // Function: PartBundle::write
// Access: Public, Virtual // Access: Published, Virtual
// Description: Writes a brief description of the bundle and all of // Description: Writes a brief description of the bundle and all of
// its descendants. // its descendants.
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
@ -238,7 +238,7 @@ write(ostream &out, int indent_level) const {
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: PartBundle::bind_anim // Function: PartBundle::bind_anim
// Access: Public // Access: Published
// Description: Binds the animation to the bundle, if possible, and // Description: Binds the animation to the bundle, if possible, and
// returns a new AnimControl that can be used to start // returns a new AnimControl that can be used to start
// and stop the animation. If the anim hierarchy does // and stop the animation. If the anim hierarchy does
@ -255,7 +255,7 @@ write(ostream &out, int indent_level) const {
// within the PartBundle; it is the user's // within the PartBundle; it is the user's
// responsibility to maintain the pointer. The // responsibility to maintain the pointer. The
// animation will automatically unbind itself when the // animation will automatically unbind itself when the
// AnimControl destructs (e.g. its reference count goes // AnimControl destructs (i.e. its reference count goes
// to zero). // to zero).
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
PT(AnimControl) PartBundle:: PT(AnimControl) PartBundle::
@ -291,7 +291,7 @@ bind_anim(AnimBundle *anim, int hierarchy_match_flags) {
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: PartBundle::bind_anim // Function: PartBundle::bind_anim
// Access: Public // Access: Published
// Description: Binds the animation to the bundle, if possible, and // Description: Binds the animation to the bundle, if possible, and
// returns a new AnimControl that can be used to start // returns a new AnimControl that can be used to start
// and stop the animation. If the anim hierarchy does // and stop the animation. If the anim hierarchy does

View File

@ -42,7 +42,7 @@ public:
// This is passed down through the MovingParts during the // This is passed down through the MovingParts during the
// do_update() call to specify the channels that are in effect. // do_update() call to specify the channels that are in effect.
typedef pmap<PT(AnimControl), float> ChannelBlend; typedef pmap<AnimControl *, float> ChannelBlend;
// This is the parameter to set_blend_type() and specifies the kind // This is the parameter to set_blend_type() and specifies the kind
// of blending operation to be performed when multiple controls are // of blending operation to be performed when multiple controls are
@ -98,17 +98,6 @@ PUBLISHED:
void set_control_effect(AnimControl *control, float effect); void set_control_effect(AnimControl *control, float effect);
float get_control_effect(AnimControl *control); float get_control_effect(AnimControl *control);
public:
// The following functions may be used to traverse the set of
// controls applied to the PartBundle. Beware! These are not safe
// to use outside of PANDA.DLL.
INLINE control_iterator control_begin() const;
INLINE control_iterator control_end() const;
INLINE control_size_type control_size() const;
INLINE const ChannelBlend &get_blend_map() const;
PUBLISHED:
virtual void output(ostream &out) const; virtual void output(ostream &out) const;
virtual void write(ostream &out, int indent_level) const; virtual void write(ostream &out, int indent_level) const;
@ -119,6 +108,15 @@ PUBLISHED:
int hierarchy_match_flags = 0); int hierarchy_match_flags = 0);
public: public:
// The following functions may be used to traverse the set of
// controls applied to the PartBundle. Beware! These are not safe
// to use outside of PANDA.DLL.
INLINE control_iterator control_begin() const;
INLINE control_iterator control_end() const;
INLINE control_size_type control_size() const;
INLINE const ChannelBlend &get_blend_map() const;
// The following functions aren't really part of the public // The following functions aren't really part of the public
// interface; they're just public so we don't have to declare a // interface; they're just public so we don't have to declare a
// bunch of friends. // bunch of friends.