/* PIKA - Photo and Image Kooker Application * a rebranding of The GNU Image Manipulation Program (created with heckimp) * A derived work which may be trivial. However, any changes may be (C)2023 by Aldercone Studio * * Original copyright, applying to most contents (license remains unchanged): * Copyright (C) 1995 Spencer Kimball and Peter Mattis * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "config.h" #include #include "core-types.h" #include "pikacontainer.h" #include "pikaobject.h" #include "pikaobjectqueue.h" #include "pikaprogress.h" typedef struct { PikaObject *object; gint64 memsize; } Item; static void pika_object_queue_dispose (GObject *object); static void pika_object_queue_push_swapped (gpointer object, PikaObjectQueue *queue); static Item * pika_object_queue_item_new (PikaObject *object); static void pika_object_queue_item_free (Item *item); G_DEFINE_TYPE (PikaObjectQueue, pika_object_queue, PIKA_TYPE_SUB_PROGRESS); #define parent_class pika_object_queue_parent_class /* private functions */ static void pika_object_queue_class_init (PikaObjectQueueClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); object_class->dispose = pika_object_queue_dispose; } static void pika_object_queue_init (PikaObjectQueue *queue) { g_queue_init (&queue->items); queue->processed_memsize = 0; queue->total_memsize = 0; } static void pika_object_queue_dispose (GObject *object) { pika_object_queue_clear (PIKA_OBJECT_QUEUE (object)); G_OBJECT_CLASS (parent_class)->dispose (object); } static void pika_object_queue_push_swapped (gpointer object, PikaObjectQueue *queue) { pika_object_queue_push (queue, object); } static Item * pika_object_queue_item_new (PikaObject *object) { Item *item = g_slice_new (Item); item->object = object; item->memsize = pika_object_get_memsize (object, NULL); return item; } static void pika_object_queue_item_free (Item *item) { g_slice_free (Item, item); } /* public functions */ PikaObjectQueue * pika_object_queue_new (PikaProgress *progress) { g_return_val_if_fail (progress == NULL || PIKA_IS_PROGRESS (progress), NULL); return g_object_new (PIKA_TYPE_OBJECT_QUEUE, "progress", progress, NULL); } void pika_object_queue_clear (PikaObjectQueue *queue) { Item *item; g_return_if_fail (PIKA_IS_OBJECT_QUEUE (queue)); while ((item = g_queue_pop_head (&queue->items))) pika_object_queue_item_free (item); queue->processed_memsize = 0; queue->total_memsize = 0; pika_sub_progress_set_range (PIKA_SUB_PROGRESS (queue), 0.0, 1.0); } void pika_object_queue_push (PikaObjectQueue *queue, gpointer object) { Item *item; g_return_if_fail (PIKA_IS_OBJECT_QUEUE (queue)); g_return_if_fail (PIKA_IS_OBJECT (object)); item = pika_object_queue_item_new (PIKA_OBJECT (object)); g_queue_push_tail (&queue->items, item); queue->total_memsize += item->memsize; } void pika_object_queue_push_container (PikaObjectQueue *queue, PikaContainer *container) { g_return_if_fail (PIKA_IS_OBJECT_QUEUE (queue)); g_return_if_fail (PIKA_IS_CONTAINER (container)); pika_container_foreach (container, (GFunc) pika_object_queue_push_swapped, queue); } void pika_object_queue_push_list (PikaObjectQueue *queue, GList *list) { g_return_if_fail (PIKA_IS_OBJECT_QUEUE (queue)); g_list_foreach (list, (GFunc) pika_object_queue_push_swapped, queue); } gpointer pika_object_queue_pop (PikaObjectQueue *queue) { Item *item; PikaObject *object; g_return_val_if_fail (PIKA_IS_OBJECT_QUEUE (queue), NULL); item = g_queue_pop_head (&queue->items); if (! item) return NULL; object = item->object; pika_sub_progress_set_range (PIKA_SUB_PROGRESS (queue), (gdouble) queue->processed_memsize / (gdouble) queue->total_memsize, (gdouble) (queue->processed_memsize + item->memsize) / (gdouble) queue->total_memsize); queue->processed_memsize += item->memsize; pika_object_queue_item_free (item); return object; }