package Mud::Obj::Event;
use strict;
use Mud::CoreTools;
use Mud::Obj;
use vars qw(@ISA);
@ISA = qw(Mud::Obj);

=head1 Description

Mud::Obj::Event keeps an object reference, method name, argument list, and 
time at which to execute. It calls the method of the object at the time, if
it is scheduled.

Event objects are immutable and persistable.

=head1 Methods

=item CM new(target => OBJ, method => METH, args => ARGS, at => TIME, after => TIME, persist => PFLAG, name => NAME)

Creates a new event object. 'at' is an absolute time at which to execute.
'after' is a delta from the current time. 'at' overrides 'after'. 'persist'
causes the object to be immediately registered with the preferred persistent
storage.

=cut

sub new {
  my ($class, %param) = @_;
  my $self = $class->SUPER::new();

  for (qw(target method)) {$param{$_} or croak "No $_ specified"}
  $param{args} ||= [];
  $param{name} ||= "";
  $param{at} ||= Mud::Scheduler->now + ($self->{after} || 0);
  my $persist = delete $param{persist};

  for (keys %param) { $self->{"event_$_"} = $param{$_}; }

  $self->register('') if $persist;

  return $self;
}

=item IM schedule()

Schedules the event for execution. If it is not already registered, it
is registered with storage 'eph', typically Mud::Storage::Ephemeral.

=cut

sub schedule {
  my ($self) = @_;
  
  $self->storage or $self->register('eph');
  Mud::Scheduler->add($self);
}

sub scheduled_event_time { return $_[0]->{event_at} }
sub scheduled_event_name { return $_[0]->{event_name} }
sub scheduled_event_run {
  my ($self) = @_;
  my $m = $self->{event_method};
  local $Carp::CarpLevel = $Carp::CarpLevel + 1;
  $self->{event_target}->$m(@{$self->{event_args}});
  
  $self->storage and $self->unregister;
  1;
}

=back

=cut

1;
__END__