### ----------------------------------------------------
### -- Gnome::Glib
### -- Licenses: Artistic-2.0
### -- Authors: Marcel Timmerman
### -- File: lib/Gnome/Glib/Source.rakumod
### ----------------------------------------------------
### -- Chunk 1 of 3
#TL:1:Gnome::Glib::Source:

use v6;
#-------------------------------------------------------------------------------
=begin pod

=head1 Gnome::Glib::Source

manages all available sources of events

=comment ![](images/X.png)

=head1 Description

To get a bigger picture, you can read the description of class B<Gnome::Glib::MainContext>.


=head1 Synopsis
=head2 Declaration

  unit class Gnome::Glib::Source;
  also is Gnome::N::TopLevelClassSupport;


=comment head2 Uml Diagram

=comment ![](plantuml/.svg)


=begin comment
=head2 Inheriting this class

Inheriting is done in a special way in that it needs a call from new() to get the native object created by the class you are inheriting from.

  use Gnome::Glib::Source:api<1>;

  unit class MyGuiClass;
  also is Gnome::Glib::Source;

  submethod new ( |c ) {
    # let the Gnome::Glib::Source class process the options
    self.bless( :N-GObject, |c);
  }

  submethod BUILD ( ... ) {
    ...
  }

=end comment
=comment head2 Example

=end pod
#-------------------------------------------------------------------------------
use NativeCall;

#use Gnome::N::X:api<1>;
use Gnome::N::NativeLib:api<1>;
use Gnome::N::N-GObject:api<1>;
use Gnome::N::GlibToRakuTypes:api<1>;
use Gnome::N::TopLevelClassSupport:api<1>;

#-------------------------------------------------------------------------------
unit class Gnome::Glib::Source:auth<github:MARTIMM>:api<1>;
also is Gnome::N::TopLevelClassSupport;


#`{{
#-------------------------------------------------------------------------------
=begin pod
=head1 Types

=head2 N-GSourceFuncs

The C<N-GSourceFuncs> struct contains a table of functions used to handle event sources in a generic manner.

For idle sources, the prepare and check functions always return TRUE to indicate that the source is always ready to be processed. The prepare function also returns a timeout value of 0 to ensure that the poll() call doesn't block (since that would be time wasted which could have been spent running the idle function).

For timeout sources, the prepare and check functions both return TRUE if the timeout interval has expired. The prepare function also returns a timeout value to ensure that the poll() call doesn't block too long and miss the next timeout.

For file descriptor sources, the prepare function typically returns FALSE, since it must wait until poll() has been called before it knows whether any events need to be processed. It sets the returned timeout to -1 to indicate that it doesn't mind how long the poll() call blocks. In the check function, it tests the results of the poll() call to see if the required condition has been met, and returns TRUE if so.

The structure of N-GSourceFuncs is

  class N-GSourceFuncs is repr('CStruct') {
    has Callable $.prepare ( N-GObject $source, gint $timeout --> gboolean ) is rw;
    has Callable $.check ( N-GObject $source --> gboolean ) is rw;
    has Callable $.dispatch (
    N-GObject source, GSourceFunc $callback, gpointer $user_data
    --> gboolean
  ) is rw;
    has Callable $.finalize ( N-GObject $source) is rw;
  };


=item function prepare

Called before all the file descriptors are polled. If the source can determine that it is ready here (without waiting for the results of the poll() call) it should return TRUE. It can also return a timeout_ value which should be the maximum timeout (in milliseconds) which should be passed to the poll() call. The actual timeout used will be -1 if all sources returned -1, or it will be the minimum of all the timeout_ values returned which were >= 0. Since 2.36 this may be NULL, in which case the effect is as if the function always returns FALSE with a timeout of -1. If prepare returns a timeout and the source also has a ready time set, then the lower of the two will be used.

  sub prepare ( N-GObject $source, gint $timeout --> gboolean )

=item function check

Called after all the file descriptors are polled. The source should return TRUE if it is ready to be dispatched. Note that some time may have passed since the previous prepare function was called, so the source should be checked again here. Since 2.36 this may be NULL, in which case the effect is as if the function always returns FALSE.


=item function dispatch

Called to dispatch the event source, after it has returned TRUE in either its prepare or its check function, or if a ready time has been reached. The dispatch function receives a callback function and user data. The callback function may be NULL if the source was never connected to a callback using g_source_set_callback(). The dispatch function should call the callback function with user_data and whatever additional parameters are needed for this type of event source. The return value of the dispatch function should be G_SOURCE_REMOVE if the source should be removed or G_SOURCE_CONTINUE to keep it.


=item function finalize

Called when the source is finalized. At this point, the source will have been destroyed, had its callback cleared, and have been removed from its GMainContext, but it will still have its final reference count, so methods can be called on it from within this function.

=end pod

subset GSourceFuncPrepare of Routine
  where .signature ~~ :( N-GObject $source, gint $timeout --> gboolean );
subset GSourceFuncCheck of Routine where .signature ~~ :( N-GObject $source --> gboolean );
subset GSourceFuncDispatch of Routine
  where .signature ~~ :(
    N-GObject source, GSourceFunc $callback, gpointer $user_data
    --> gboolean
  );
subset GSourceFuncFinalize of Routine where .signature ~~ :( N-GObject $source);

#TT:0:N-GSourceFuncs:
class N-GSourceFuncs is repr('CStruct') {
  has GSourceFuncPrepare $.prepare is rw;
  has GSourceFuncCheck $.check is rw;
  has GSourceFuncDispatch $.dispatch is rw;
  has GSourceFuncFinalize $.finalize is rw;
};
}}

#-------------------------------------------------------------------------------
=begin pod
=head1 Methods
=head2 new

=head3 :idle

Create a new Source object to run processes in idle time. The source will not initially be associated with any B<Gnome::Glib::MainContext> and must be added to one with C<attach()> before it will be executed. Note that the default priority for idle sources is C<G-PRIORITY-DEFAULT-IDLE>, as compared to other sources which have a default priority of C<G-PRIORITY-DEFAULT>.

  multi method new ( :idle! )


=head3 :timout

Creates a new timeout source. The source will not initially be associated with any B<Gnome::Glib::MainContext> and must be added to one with C<attach()> before it will be executed.

The interval given is in terms of monotonic time, not wall clock time. See C<get-monotonic-time()>.

  multi method new ( Int :$timeout!, Bool :$seconds = False )

=item UInt $interval; the timeout interval in milliseconds.


=head3 :native-object

Create a Source object using a native object from elsewhere. See also B<Gnome::N::TopLevelClassSupport>.

  multi method new ( N-GObject :$native-object! )

=end pod

#TM:1:new(:idle):
#TM:4:new(:native-object):Gnome::N::TopLevelClassSupport
submethod BUILD ( *%options ) {

  # prevent creating wrong native-objects
  if self.^name eq 'Gnome::Glib::Source' #`{{ or %options<GSource> }} {

    # check if native object is set by a parent class
    if self.is-valid { }

    # check if common options are handled by some parent
    elsif %options<native-object>:exists { }
    elsif %options<build-id>:exists { }

    # process all other options
    else {
      my $no;
      if %options<idle>:exists {
        $no = _g_idle_source_new;
      }

      elsif ? %options<timeout> {
        my Bool $seconds = %options<seconds> // False;
        if $seconds {
          $no = _g_timeout_source_new_seconds(%options<timeout>);
        }

        else {
          $no = _g_timeout_source_new(%options<timeout>);
        }
      }

      ##`{{ use this when the module is not made inheritable
      # check if there are unknown options
      elsif %options.elems {
        die X::Gnome.new(
          :message(
            'Unsupported, undefined, incomplete or wrongly typed options for ' ~
            self.^name ~ ': ' ~ %options.keys.join(', ')
          )
        );
      }
      #}}

      ##`{{ when there are no defaults use this
      # check if there are any options
      elsif %options.elems == 0 {
        die X::Gnome.new(:message('No options specified ' ~ self.^name));
      }
      #}}

      #`{{ when there are defaults use this instead
      # create default object
      else {
        $no = _g_source_new();
      }
      }}

      self._set-native-object($no);
    }

    # only after creating the native-object, the gtype is known
    self._set-class-info('GSource');
  }
}

#-------------------------------------------------------------------------------
method native-object-ref ( $n-native-object --> N-GObject ) {
  _g_source_ref($n-native-object)
}

#-------------------------------------------------------------------------------
method native-object-unref ( $n-native-object ) {
  _g_source_unref($n-native-object)
}

#`{{
#-------------------------------------------------------------------------------
#TM:0:add-child-source:
=begin pod
=head2 add-child-source

Adds I<child-source> to I<source> as a "polled" source; when I<source> is added to a B<Gnome::Glib::MainContext>, I<child-source> will be automatically added with the same priority, when I<child-source> is triggered, it will cause I<source> to dispatch (in addition to calling its own callback), and when I<source> is destroyed, it will destroy I<child-source> as well. (I<source> will also still be dispatched if its own prepare/check functions indicate that it is ready.)

If you don't need I<child-source> to do anything on its own when it triggers, you can call C<set-dummy-callback()> on it to set a callback that does nothing (except return C<True> if appropriate).

I<source> will hold a reference on I<child-source> while I<child-source> is attached to it.

This API is only intended to be used by implementations of B<Gnome::Glib::Source>. Do not call this API on a B<Gnome::Glib::Source> that you did not create.

  method add-child-source ( N-GObject $child_source )

=item N-GObject $child_source; a second B<Gnome::Glib::Source> that I<source> should "poll"
=end pod

method add-child-source ( N-GObject $child_source ) {

  g_source_add_child_source(
    self._get-native-object-no-reffing, $child_source
  );
}

sub g_source_add_child_source (
  N-GObject $source, N-GObject $child_source
) is native(&glib-lib)
  { * }

#`{{
#-------------------------------------------------------------------------------
#TM:0:add-poll:
=begin pod
=head2 add-poll

Adds a file descriptor to the set of file descriptors polled for this source. This is usually combined with C<new()> to add an event source. The event source's check function will typically test the I<revents> field in the B<Gnome::Glib::PollFD> struct and return C<True> if events need to be processed.

This API is only intended to be used by implementations of B<Gnome::Glib::Source>. Do not call this API on a B<Gnome::Glib::Source> that you did not create.

Using this API forces the linear scanning of event sources on each main loop iteration. Newly-written event sources should try to use C<g-source-add-unix-fd()> instead of this API.

  method add-poll ( GPollFD $fd )

=item GPollFD $fd; a B<Gnome::Glib::PollFD> structure holding information about a file descriptor to watch.
=end pod

method add-poll ( GPollFD $fd ) {

  g_source_add_poll(
    self._get-native-object-no-reffing, $fd
  );
}

sub g_source_add_poll (
  N-GObject $source, GPollFD $fd
) is native(&glib-lib)
  { * }

#-------------------------------------------------------------------------------
#TM:0:add-unix-fd:
=begin pod
=head2 add-unix-fd

Monitors I<fd> for the IO events in I<events>.

The tag returned by this function can be used to remove or modify the monitoring of the fd using C<remove-unix-fd()> or C<g-source-modify-unix-fd()>.

It is not necessary to remove the fd before destroying the source; it will be cleaned up automatically.

This API is only intended to be used by implementations of B<Gnome::Glib::Source>. Do not call this API on a B<Gnome::Glib::Source> that you did not create.

As the name suggests, this function is not available on Windows.

Returns: an opaque tag

  method add-unix-fd ( Int $fd, GIOCondition $events --> Pointer )

=item Int $fd; the fd to monitor
=item GIOCondition $events; an event mask
=end pod

method add-unix-fd ( Int $fd, GIOCondition $events --> Pointer ) {

  g_source_add_unix_fd(
    self._get-native-object-no-reffing, $fd, $events
  )
}

sub g_source_add_unix_fd (
  N-GObject $source, gint $fd, GIOCondition $events --> gpointer
) is native(&glib-lib)
  { * }
}}
}}

#-------------------------------------------------------------------------------
#TM:0:attach:
=begin pod
=head2 attach

Adds a B<Gnome::Glib::Source> to a I<context> so that it will be executed within that context. Remove it by calling C<destroy()>.

Returns: the ID (greater than 0) for the source within the B<Gnome::Glib::MainContext>.

  method attach ( N-GObject $context --> UInt )

=item N-GObject $context; a B<Gnome::Glib::MainContext> (if C<undefined>, the default context will be used)
=end pod

method attach ( $context is copy --> UInt ) {
  $context .= _get-native-object-no-reffing unless $context ~~ N-GObject;
  g_source_attach( self._get-native-object-no-reffing, $context)
}

sub g_source_attach (
  N-GObject $source, N-GObject $context --> guint
) is native(&glib-lib)
  { * }

#-------------------------------------------------------------------------------
#TM:0:destroy:
=begin pod
=head2 destroy

Removes a source from its B<Gnome::Glib::MainContext>, if any, and mark it as destroyed. The source cannot be subsequently added to another context. It is safe to call this on sources which have already been removed from their context.

  method destroy ( )

=end pod

method destroy ( ) {
  g_source_destroy(self._get-native-object-no-reffing);
}

sub g_source_destroy ( N-GObject $source )
  is native(&glib-lib)
  { * }

#`{{
#-------------------------------------------------------------------------------
#TM:0:g-child-watch-add:
=begin pod
=head2 g-child-watch-add

Sets a function to be called when the child indicated by I<pid> exits, at a default priority, C<G-PRIORITY-DEFAULT>.

If you obtain I<pid> from C<g-spawn-async()> or C<g-spawn-async-with-pipes()> you will need to pass B<Gnome::Glib::-SPAWN-DO-NOT-REAP-CHILD> as flag to the spawn function for the child watching to work.

Note that on platforms where B<Gnome::Glib::Pid> must be explicitly closed (see C<g-spawn-close-pid()>) I<pid> must not be closed while the source is still active. Typically, you will want to call C<g-spawn-close-pid()> in the callback function for the source.

GLib supports only a single callback per process id. On POSIX platforms, the same restrictions mentioned for C<g-child-watch-source-new()> apply to this function.

This internally creates a main loop source using C<g-child-watch-source-new()> and attaches it to the main loop context using C<attach()>. You can do these steps manually if you need greater control.

Returns: the ID (greater than 0) of the event source.

  method g-child-watch-add ( GPid $pid, GChildWatchFunc $function, Pointer $data --> UInt )

=item GPid $pid; process id to watch. On POSIX the positive pid of a child process. On Windows a handle for a process (which doesn't have to be a child).
=item GChildWatchFunc $function; function to call
=item Pointer $data; data to pass to I<function>
=end pod

method g-child-watch-add ( GPid $pid, GChildWatchFunc $function, Pointer $data --> UInt ) {

  g_child_watch_add(
    self._get-native-object-no-reffing, $pid, $function, $data
  )
}

sub g_child_watch_add (
  GPid $pid, GChildWatchFunc $function, gpointer $data --> guint
) is native(&glib-lib)
  { * }

#-------------------------------------------------------------------------------
#TM:0:g-child-watch-add-full:
=begin pod
=head2 g-child-watch-add-full

Sets a function to be called when the child indicated by I<pid> exits, at the priority I<priority>.

If you obtain I<pid> from C<g-spawn-async()> or C<g-spawn-async-with-pipes()> you will need to pass B<Gnome::Glib::-SPAWN-DO-NOT-REAP-CHILD> as flag to the spawn function for the child watching to work.

In many programs, you will want to call C<g-spawn-check-exit-status()> in the callback to determine whether or not the child exited successfully.

Also, note that on platforms where B<Gnome::Glib::Pid> must be explicitly closed (see C<g-spawn-close-pid()>) I<pid> must not be closed while the source is still active. Typically, you should invoke C<g-spawn-close-pid()> in the callback function for the source.

GLib supports only a single callback per process id. On POSIX platforms, the same restrictions mentioned for C<g-child-watch-source-new()> apply to this function.

This internally creates a main loop source using C<g-child-watch-source-new()> and attaches it to the main loop context using C<attach()>. You can do these steps manually if you need greater control.

Returns: the ID (greater than 0) of the event source.

  method g-child-watch-add-full ( Int $priority, GPid $pid, GChildWatchFunc $function, Pointer $data, GDestroyNotify $notify --> UInt )

=item Int $priority; the priority of the idle source. Typically this will be in the range between C<G-PRIORITY-DEFAULT-IDLE> and C<G-PRIORITY-HIGH-IDLE>.
=item GPid $pid; process to watch. On POSIX the positive pid of a child process. On Windows a handle for a process (which doesn't have to be a child).
=item GChildWatchFunc $function; function to call
=item Pointer $data; data to pass to I<function>
=item GDestroyNotify $notify; function to call when the idle is removed, or C<undefined>
=end pod

method g-child-watch-add-full ( Int $priority, GPid $pid, GChildWatchFunc $function, Pointer $data, GDestroyNotify $notify --> UInt ) {

  g_child_watch_add_full(
    self._get-native-object-no-reffing, $priority, $pid, $function, $data, $notify
  )
}

sub g_child_watch_add_full (
  gint $priority, GPid $pid, GChildWatchFunc $function, gpointer $data, GDestroyNotify $notify --> guint
) is native(&glib-lib)
  { * }

#-------------------------------------------------------------------------------
#TM:0:g-child-watch-source-new:
=begin pod
=head2 g-child-watch-source-new

Creates a new child-watch source.

The source will not initially be associated with any B<Gnome::Glib::MainContext> and must be added to one with C<attach()> before it will be executed.

Note that child watch sources can only be used in conjunction with `g-spawn...` when the C<G-SPAWN-DO-NOT-REAP-CHILD> flag is used.

Note that on platforms where B<Gnome::Glib::Pid> must be explicitly closed (see C<g-spawn-close-pid()>) I<pid> must not be closed while the source is still active. Typically, you will want to call C<g-spawn-close-pid()> in the callback function for the source.

On POSIX platforms, the following restrictions apply to this API due to limitations in POSIX process interfaces:

* I<pid> must be a child of this process * I<pid> must be positive * the application must not call `waitpid` with a non-positive first argument, for instance in another thread * the application must not wait for I<pid> to exit by any other mechanism, including `waitpid(pid, ...)` or a second child-watch source for the same I<pid> * the application must not ignore SIGCHILD

If any of those conditions are not met, this and related APIs will not work correctly. This can often be diagnosed via a GLib warning stating that `ECHILD` was received by `waitpid`.

Calling `waitpid` for specific processes other than I<pid> remains a valid thing to do.

Returns: the newly-created child watch source

  method g-child-watch-source-new ( GPid $pid --> N-GObject )

=item GPid $pid; process to watch. On POSIX the positive pid of a child process. On Windows a handle for a process (which doesn't have to be a child).
=end pod

method g-child-watch-source-new ( GPid $pid --> N-GObject ) {

  g_child_watch_source_new(
    self._get-native-object-no-reffing, $pid
  )
}

sub g_child_watch_source_new (
  GPid $pid --> N-GObject
) is native(&glib-lib)
  { * }

#-------------------------------------------------------------------------------
#TM:0:g-clear-handle-id:
=begin pod
=head2 g-clear-handle-id

Clears a numeric handler, such as a B<Gnome::Glib::Source> ID.

I<tag-ptr> must be a valid pointer to the variable holding the handler.

If the ID is zero then this function does nothing. Otherwise, C<clear-func()> is called with the ID as a parameter, and the tag is set to zero.

A macro is also included that allows this function to be used without pointer casts.

  method g-clear-handle-id ( guInt-ptr $tag_ptr, GClearHandleFunc $clear_func )

=item guInt-ptr $tag_ptr; a pointer to the handler ID
=item GClearHandleFunc $clear_func; the function to call to clear the handler
=end pod

method g-clear-handle-id ( guInt-ptr $tag_ptr, GClearHandleFunc $clear_func ) {

  g_clear_handle_id(
    self._get-native-object-no-reffing, $tag_ptr, $clear_func
  );
}

sub g_clear_handle_id (
  gugint-ptr $tag_ptr, GClearHandleFunc $clear_func
) is native(&glib-lib)
  { * }

#-------------------------------------------------------------------------------
#TM:0:g-get-current-time:
=begin pod
=head2 g-get-current-time

Equivalent to the UNIX C<gettimeofday()> function, but portable.

You may find C<g-get-real-time()> to be more convenient.

  method g-get-current-time ( GTimeVal $result )

=item GTimeVal $result; B<Gnome::Glib::TimeVal> structure in which to store current time.
=end pod

method g-get-current-time ( GTimeVal $result ) {

  g_get_current_time(
    self._get-native-object-no-reffing, $result
  );
}

sub g_get_current_time (
  GTimeVal $result
) is native(&glib-lib)
  { * }
}}

#-------------------------------------------------------------------------------
#TM:0:get-monotonic-time:
=begin pod
=head2 get-monotonic-time

Queries the system monotonic time.

The monotonic clock will always increase and doesn't suffer discontinuities when the user (or NTP) changes the system time. It may or may not continue to tick during times where the machine is suspended.

We try to use the clock that corresponds as closely as possible to the passage of time as measured by system calls such as C<poll()> but it may not always be possible to do this.

Returns: the monotonic time, in microseconds

  method get-monotonic-time ( --> Int )

=end pod

method get-monotonic-time ( --> Int ) {
  g_get_monotonic_time
}

sub g_get_monotonic_time ( --> gint64 )
  is native(&glib-lib)
  { * }

#-------------------------------------------------------------------------------
#TM:0:get-real-time:
=begin pod
=head2 get-real-time

Queries the system wall-clock time.

This call is functionally equivalent to C<g-get-current-time()> except that the return value is often more convenient than dealing with a B<Gnome::Glib::TimeVal>.

You should only use this call if you are actually interested in the real wall-clock time. C<g-get-monotonic-time()> is probably more useful for measuring intervals.

Returns: the number of microseconds since January 1, 1970 UTC.

  method get-real-time ( --> Int )

=end pod

method get-real-time ( --> Int ) {

  g_get_real_time
}

sub g_get_real_time ( --> gint64 )
  is native(&glib-lib)
  { * }

#-------------------------------------------------------------------------------
#TM:0:get-can-recurse:
=begin pod
=head2 get-can-recurse

Checks whether a source is allowed to be called recursively. see C<set-can-recurse()>.

Returns: whether recursion is allowed.

  method get-can-recurse ( --> Bool )

=end pod

method get-can-recurse ( --> Bool ) {

  g_source_get_can_recurse(
    self._get-native-object-no-reffing,
  ).Bool
}

sub g_source_get_can_recurse (
  N-GObject $source --> gboolean
) is native(&glib-lib)
  { * }

#-------------------------------------------------------------------------------
#TM:0:get-context:
=begin pod
=head2 get-context

Gets the B<Gnome::Glib::MainContext> with which the source is associated.

You can call this on a source that has been destroyed, provided that the B<Gnome::Glib::MainContext> it was attached to still exists (in which case it will return that B<Gnome::Glib::MainContext>). In particular, you can always call this function on the source returned from C<g-main-current-source()>. But calling this function on a source whose B<Gnome::Glib::MainContext> has been destroyed is an error.

Returns: the B<Gnome::Glib::MainContext> with which the source is associated, or C<undefined> if the context has not yet been added to a source.

  method get-context ( --> N-GObject )

=end pod

method get-context ( --> N-GObject ) {

  g_source_get_context(
    self._get-native-object-no-reffing,
  )
}

sub g_source_get_context (
  N-GObject $source --> N-GObject
) is native(&glib-lib)
  { * }

#-------------------------------------------------------------------------------
#TM:0:get-id:
=begin pod
=head2 get-id

Returns the numeric ID for a particular source. The ID of a source is a positive integer which is unique within a particular main loop context. The reverse mapping from ID to source is done by C<g-main-context-find-source-by-id()>.

You can only call this function while the source is associated to a B<Gnome::Glib::MainContext> instance; calling this function before C<attach()> or after C<g-source-destroy()> yields undefined behavior. The ID returned is unique within the B<Gnome::Glib::MainContext> instance passed to C<g-source-attach()>.

Returns: the ID (greater than 0) for the source

  method get-id ( --> UInt )

=end pod

method get-id ( --> UInt ) {
  g_source_get_id(self._get-native-object-no-reffing)
}

sub g_source_get_id (
  N-GObject $source --> guint
) is native(&glib-lib)
  { * }

#-------------------------------------------------------------------------------
#TM:0:get-name:
=begin pod
=head2 get-name

Gets a name for the source, used in debugging and profiling. The name may be B<NULL> if it has never been set with C<set-name()>.

Returns: the name of the source

  method get-name ( --> Str )

=end pod

method get-name ( --> Str ) {
  g_source_get_name(self._get-native-object-no-reffing)
}

sub g_source_get_name (
  N-GObject $source --> gchar-ptr
) is native(&glib-lib)
  { * }

#-------------------------------------------------------------------------------
#TM:0:get-priority:
=begin pod
=head2 get-priority

Gets the priority of a source.

Returns: the priority of the source

  method get-priority ( --> Int )

=end pod

method get-priority ( --> Int ) {
  g_source_get_priority(self._get-native-object-no-reffing)
}

sub g_source_get_priority (
  N-GObject $source --> gint
) is native(&glib-lib)
  { * }

#-------------------------------------------------------------------------------
#TM:0:get-ready-time:
=begin pod
=head2 get-ready-time

Gets the "ready time" of I<source>, as set by C<set-ready-time()>.

Any time before the current monotonic time (including 0) is an indication that the source will fire immediately.

Returns: the monotonic ready time, -1 for "never"

  method get-ready-time ( --> Int )

=end pod

method get-ready-time ( --> Int ) {
  g_source_get_ready_time(self._get-native-object-no-reffing)
}

sub g_source_get_ready_time (
  N-GObject $source --> gint64
) is native(&glib-lib)
  { * }

#-------------------------------------------------------------------------------
#TM:0:get-time:
=begin pod
=head2 get-time

Gets the time to be used when checking this source. The advantage of calling this function over calling C<g-get-monotonic-time()> directly is that when checking multiple sources, GLib can cache a single value instead of having to repeatedly get the system monotonic time.

The time here is the system monotonic time, if available, or some other reasonable alternative otherwise. See C<g-get-monotonic-time()>.

Returns: the monotonic time in microseconds

  method get-time ( --> Int )

=end pod

method get-time ( --> Int ) {
  g_source_get_time(self._get-native-object-no-reffing)
}

sub g_source_get_time (
  N-GObject $source --> gint64
) is native(&glib-lib)
  { * }

#-------------------------------------------------------------------------------
#TM:0:idle-add:
=begin pod
=head2 idle-add

Adds a function to be called whenever there are no higher priority events pending to the default main loop. The function is given the default idle priority, C<G-PRIORITY-DEFAULT-IDLE>. If the function returns C<False> it is automatically removed from the list of event sources and will not be called again.

=comment See [memory management of sources][mainloop-memory-management] for details on how to handle the return value and memory management of I<data>.

This internally creates a main loop source using C<g-idle-source-new()> and attaches it to the global B<Gnome::Glib::MainContext> using C<attach()>, so the callback will be invoked in whichever thread is running that main context. You can do these steps manually if you need greater control or to use a custom main context.

Returns: the ID (greater than 0) of the event source.

  method idle-add (
    Any:D $handler-object, Str:D $method, *%user-options
    --> UInt
  )

=item $handler-object; User object where $method is defined
=item Str $method; name of callback handler
=item %user-options; optional named arguments to be provided to the callback

=end pod

method idle-add (
  Any:D $handler-object, Str:D $method, *%user-options
  --> UInt
) {
  die X::Gnome.new(:message("Method $method or handler object not found"))
    unless $handler-object.^can($method);

  g_idle_add(
    sub ( gpointer $d --> gboolean ) {
      $handler-object."$method"(|%user-options);
    },
    gpointer
  )
}

sub g_idle_add (
  Callable $func ( gpointer --> gboolean ),
  gpointer $data --> guint
) is native(&glib-lib)
  { * }

#-------------------------------------------------------------------------------
#TM:0:idle-add-full:
=begin pod
=head2 idle-add-full

Adds a function to be called whenever there are no higher priority events pending. If the function returns C<False> it is automatically removed from the list of event sources and will not be called again.

=comment See [memory management of sources][mainloop-memory-management] for details on how to handle the return value and memory management of I<data>.

This internally creates a main loop source using C<g-idle-source-new()> and attaches it to the global B<Gnome::Glib::MainContext> using C<attach()>, so the callback will be invoked in whichever thread is running that main context. You can do these steps manually if you need greater control or to use a custom main context.

Returns: the ID (greater than 0) of the event source.

  method idle-add-full (
    Int $priority,
    Any:D $handler-object, Str:D $method, Str $method-notify = Str,
    *%user-options
    --> UInt
  )

=item Int $priority; the priority of the idle source. Typically this will be in the range between C<G-PRIORITY-DEFAULT-IDLE> and C<G-PRIORITY-HIGH-IDLE>.
=item $handler-object; User object where both methods are defined
=item Str $method; name of callback handler
=item Str $method-notify; name of callback handler. Ignored when $method-notify is undefined. This function is called when the source is removed.
=item %user-options; optional named arguments to be provided to both callbacks
=end pod

method idle-add-full (
  Int $priority,
  Any:D $handler-object, Str:D $method, Str $method-notify = Str,
  *%user-options
  --> UInt
) {
  die X::Gnome.new(:message("Method $method or handler object not found"))
    unless $handler-object.^can($method);

  if ?$method-notify and $handler-object.can($method-notify) {
    g_idle_add_full(
      $priority,
      sub ( gpointer $d --> gboolean ) {
        $handler-object."$method"(|%user-options);
      }, gpointer,
      sub ( gpointer $d ) {
        $handler-object."$method-notify"(|%user-options);
      },
    )
  }

  else {
    g_idle_add_full(
      $priority,
      sub ( gpointer $d --> gboolean ) {
        $handler-object."$method"(|%user-options);
      }, gpointer,
      Nil
    )
  }
}

sub g_idle_add_full (
  gint $priority,
  Callable $func ( gpointer --> gboolean ), gpointer $data,
  Callable $notify ( gpointer )
  --> guint
) is native(&glib-lib)
  { * }

#`{{
#-------------------------------------------------------------------------------
#TM:0:idle-remove-by-data:
=begin pod
=head2 idle-remove-by-data

Removes the idle function with the given data.

Returns: C<True> if an idle source was found and removed.

  method idle-remove-by-data ( Pointer $data --> Bool )

=item Pointer $data; the data for the idle source's callback.
=end pod

method idle-remove-by-data ( Pointer $data --> Bool ) {

  g_idle_remove_by_data(
    self._get-native-object-no-reffing, $data
  ).Bool
}

sub g_idle_remove_by_data (
  gpointer $data --> gboolean
) is native(&glib-lib)
  { * }
}}

#-------------------------------------------------------------------------------
#TM:1:_g_idle_source_new:
#`{{
=begin pod
=head2 g-idle-source-new

Creates a new idle source.

The source will not initially be associated with any B<Gnome::Glib::MainContext> and must be added to one with C<attach()> before it will be executed. Note that the default priority for idle sources is C<G-PRIORITY-DEFAULT-IDLE>, as compared to other sources which have a default priority of C<G-PRIORITY-DEFAULT>.

Returns: the newly-created idle source

  method g-idle-source-new ( --> N-GObject )

=end pod

method g-idle-source-new ( --> N-GObject ) {

  g_idle_source_new
}
}}

sub _g_idle_source_new ( --> N-GObject )
  is native(&glib-lib)
  is symbol('g_idle_source_new')
  { * }

#`{{
#-------------------------------------------------------------------------------
#TM:0:is-destroyed:
=begin pod
=head2 is-destroyed

Returns whether I<source> has been destroyed.

This is important when you operate upon your objects from within idle handlers, but may have freed the object before the dispatch of your idle handler.

=begin comment
static gboolean
idle_callback