correction to mrp-assignment.c patch



Hi all,

apologies - the recent patch I submitted for mrp-assignment.c doesn't take account of the asymmetrical nature of 'units_in_use' (i.e., units_in_use stores units to the right of an edge). As a result, whilst the code for mrp_assignment_edges_remove_from_first_after does exactly what it says, it is not a useful routine to deploy in resource overallocation calculations.

I have replaced the function with the simpler mrp_assignment_edges_remove_after, which is more useful. Hopefully this will get through before those patches make it to commit!

Also attached are the updated call to the function in mrp-resource.c, as well as the header and changelog.

Sorry about that!
lee
Index: ChangeLog
===================================================================
--- ChangeLog	(revision 940)
+++ ChangeLog	(working copy)
@@ -1,3 +1,40 @@
+2008-11-28  Lee Baylis <lee leebaylis co uk>
+
+	* libplanner/mrp-assignment.c (assignment_edge_compare),
+	(mrp_assignment_edges_insert_sorted_from_assignment),
+	(mrp_assignment_edges_insert_sorted_from_assignment_list),
+	(mrp_assignment_edges_plot_units_in_use),
+	(mrp_assignment_edges_calculate_max_units_in_use),
+	(mrp_assignment_edges_remove_to_last_before),
+	(mrp_assignment_edges_remove_after),
+	(mrp_assignment_edge_get_delta_units):
+	  Moved and changed Date struct from planner-usage-row to become
+		MrpAssignmentEdge struct;
+	  Introduced functions for creating and manipulating lists of 
+		MrpAssignmentEdge objects.
+	* libplanner/mrp-assignment.h:
+	* libplanner/mrp-resource.c (mrp_resource_get_assignment_edges),
+	(mrp_resource_allocation_status),
+	(mrp_resource_test_if_overallocated),
+	(resource_get_edges_with_units_in_use),
+	(mrp_resource_get_max_units_used_between),
+	(mrp_resource_get_available_units_between),
+	(mrp_resource_get_available_units_during):
+	  Moved logic for calculating overallocation from planner-usage-row;
+	  Introduced functions for listing and analysing a resource's 
+		MrpAssignmentEdge objects;
+	  Introduced resource overallocation test function.
+	* libplanner/mrp-resource.h:
+	* src/planner-usage-row.c (usage_row_realize),
+	(usage_row_draw_resource_ival), (usage_row_draw_resource),
+	(usage_row_draw_assignment): 
+	  Moved Date & date_type structs and the date_compare 
+		function to mrp-assignment;
+	  Moved code which initialised Dates to mrp-assignment;
+	  Replaced 12 color variables with 4 color_scheme structs 
+		and matched them to overallocation scenarios;
+	  Moved logic for calculating overallocation to mrp-resource.
+
 2008-11-05  Maurice van der Pot  <griffon26 kfk4ever com>
 
 	* libplanner/mrp-parser.c: Removed unused function.
Index: libplanner/mrp-assignment.c
===================================================================
--- libplanner/mrp-assignment.c	(revision 940)
+++ libplanner/mrp-assignment.c	(working copy)
@@ -3,6 +3,7 @@
  * Copyright (C) 2001-2003 CodeFactory AB
  * Copyright (C) 2001-2003 Richard Hult <richard imendio com>
  * Copyright (C) 2001-2002 Mikael Hallendal <micke imendio com>
+ * Copyright (C) 2008      Lee Baylis <lee leebaylis co uk>
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
@@ -43,19 +44,20 @@
         PROP_UNITS
 };
 
+static void    assignment_class_init   (MrpAssignmentClass         *klass);
+static void    assignment_init         (MrpAssignment              *assignment);
+static void    assignment_finalize     (GObject                    *object);
+static void    assignment_set_property (GObject                    *object,
+					guint                       prop_id,
+					const GValue               *value,
+					GParamSpec                 *pspec);
+static void    assignment_get_property (GObject                    *object,
+					guint                       prop_id,
+					GValue                     *value,
+					GParamSpec                 *pspec);
+static gint    assignment_edge_compare (gconstpointer               edge1,
+					gconstpointer               edge2); 
 
-static void assignment_class_init        (MrpAssignmentClass *klass);
-static void assignment_init              (MrpAssignment      *assignment);
-static void assignment_finalize          (GObject            *object);
-static void assignment_set_property      (GObject            *object,
-					  guint               prop_id,
-					  const GValue       *value,
-					  GParamSpec         *pspec);
-static void assignment_get_property      (GObject            *object,
-					  guint               prop_id,
-					  GValue             *value,
-					  GParamSpec         *pspec);
-
 static MrpObjectClass *parent_class;
 
 GType
@@ -226,6 +228,33 @@
 	}
 }
 
+static gint
+assignment_edge_compare (gconstpointer edge1,
+			 gconstpointer edge2)
+{
+        const MrpAssignmentEdge *a, *b;
+
+	a = edge1;
+        b = edge2;
+
+	if (a->time < b->time) {
+                return -1;
+        }
+	else if (a->time == b->time) {
+		/* if times are equal, overallocation calculations require that end_edges are sorted before start_edges */
+                if (a->type < b->type) {
+                        return 1;
+                }
+		else if (a->type == b->type) {
+                        return 0;
+                } else {
+                        return -1;
+                }
+        } else {
+                return 1;
+        }
+}
+
 /**
  * mrp_assignment_new:
  *
@@ -267,8 +296,8 @@
  * 
  * Retrieves the #MrpResource associated with @assignment.
  * 
- * Return value: the resource associated with the assignment object. The reference
- * count of the resource is not increased.
+ * Return value: the resource associated with the assignment object. 
+ * The reference count of the resource is not increased.
  **/
 MrpResource *
 mrp_assignment_get_resource (MrpAssignment *assignment)
@@ -294,3 +323,210 @@
 	
 	return assignment->priv->units;
 }
+
+/**
+ * mrp_assignment_edges_insert_sorted_from_assignment:
+ * @edges: a #GList optionally containing #MrpAssignmentEdge objects
+ * @assignment: an #MrpAssignment
+ *
+ * Determines the start and end edges (essentially times + assignment units) 
+ * from an assignment's associated task, and inserts them into the list of 
+ * edges sorted by mrptime. Mostly useful for tracking a MrpResource's 
+ * total assignment units whilst scanning across a project.
+ *
+ * Return Value: pointer to the updated edges GList.
+ **/
+GList *
+mrp_assignment_edges_insert_sorted_from_assignment (GList *edges,
+						    MrpAssignment *assignment)
+{
+	MrpTask           *task;
+	gint              units;
+	MrpAssignmentEdge *start_edge, *end_edge;
+
+	g_return_val_if_fail (MRP_IS_ASSIGNMENT (assignment), edges);
+
+	task = mrp_assignment_get_task (assignment);
+	units = mrp_assignment_get_units (assignment);
+
+	start_edge = g_new0 (MrpAssignmentEdge, 1);
+	start_edge->type = START_EDGE;
+	start_edge->time = mrp_task_get_work_start(task);
+	start_edge->units = units;
+	start_edge->assignment = assignment;
+	start_edge->task = task;
+	
+	edges = g_list_insert_sorted (edges, start_edge, assignment_edge_compare);
+	
+	end_edge = g_new0 (MrpAssignmentEdge, 1);
+	end_edge->type = END_EDGE;
+	end_edge->time = mrp_task_get_finish(task);
+	end_edge->units = units;
+	end_edge->assignment = assignment;
+	end_edge->task = task;
+	
+	edges = g_list_insert_sorted (edges, end_edge, assignment_edge_compare);
+        
+	return edges;
+}
+
+/**
+ * mrp_assignment_edges_insert_sorted_from_assignment_list:
+ * @edges: a #GList containing #MrpAssignmentEdge objects
+ * @assignments: a #GList contianing #MrpAssignment objects
+ *
+ * Determines the sorted start and end edges for all passed assignments. 
+ * Mostly useful for scanning a #MrpResource object's total assignment 
+ * units across a project.
+ *
+ * Return Value: pointer to the updated edges #GList.
+ **/
+GList *
+mrp_assignment_edges_insert_sorted_from_assignment_list (GList *edges,
+							 GList *assignments)
+{
+	GList         *a;
+	MrpAssignment *assignment;
+
+	for (a = assignments; a; a = a->next) {
+                assignment = a->data;
+		edges = mrp_assignment_edges_insert_sorted_from_assignment(edges, assignment);
+	}
+	return edges;
+}
+
+/**
+ * mrp_assignment_edges_plot_units_in_use:
+ * @edges: a #GList containing #MrpAssignmentEdge objects
+ *
+ * Iterates the #GList of #MrpAssignmentEdge objects calculating a 
+ * running total for each #MrpAssignmentEdge by adding units for 
+ * start edges and subtracting them for end edges. Mostly useful for 
+ * calculating a #MrpResource object's allocation within a period.
+ *
+ * Return Value: pointer to the updated edges #GList.
+ **/
+GList *
+mrp_assignment_edges_plot_units_in_use (GList *edges)
+{
+	GList *e;
+	MrpAssignmentEdge *edge;
+	gint units = 0;
+
+        for (e = edges; e; e = e->next) {
+		edge = e->data;
+		units += mrp_assignment_edge_get_delta_units(edge);
+		edge->units_in_use = units;
+	}
+	return edges;
+}
+
+/**
+ * mrp_assignment_edges_calculate_max_units_in_use:
+ * @edges: a #GList containing #MrpAssignmentEdge objects
+ *
+ * Iterates the #GList of #MrpAssignmentEdge objects consulting the 
+ * running total for each #MrpAssignmentEdge and storing the maximum.
+ *
+ * Return Value: #gint containing the maximum units in use.
+ **/
+gint 
+mrp_assignment_edges_calculate_max_units_in_use (GList *edges)
+{
+	GList             *e;
+	MrpAssignmentEdge *edge;
+	gint               units = 0;
+
+	for (e = edges; e; e = e->next){
+		edge = e->data;
+		if (edge->units_in_use > units) {
+			units = edge->units_in_use;
+		}
+	}
+	return units;
+}
+
+/**
+ * mrp_assignment_edges_remove_to_last_before:
+ * @edges: a #GList containing #MrpAssignmentEdge objects
+ * @time: a #mrptime
+ *
+ * Removes all but the last #MrpAssignmentEdge object before @time from @edges.
+ * Mostly useful for isolating time periods for later calculation.
+ *
+ * Return Value: pointer to the updated edges #GList.
+ **/
+GList * 
+mrp_assignment_edges_remove_to_last_before(GList *edges,
+					   mrptime time)
+{
+	GList             *e;
+	MrpAssignmentEdge *edge;
+	
+	if (edges){
+		e = edges->next;
+		if (e){
+			edge = e->data;
+			while (edge->time <= time){
+				edges = g_list_delete_link(edges, edges);
+				e = edges->next;
+				if (!e) {break;}
+				edge = e->data;
+			}
+		}
+	}
+	return edges;
+}
+
+/**
+ * mrp_assignment_edges_remove_after:
+ * @edges: a #GList containing #MrpAssignmentEdge objects
+ * @time: a #mrptime
+ *
+ * Removes all #MrpAssignmentEdge objects after @time from @edges.
+ * Mostly useful for isolating time periods for later calculation.
+ *
+ * Return Value: pointer to the updated edges #GList.
+ **/
+GList * 
+mrp_assignment_edges_remove_after(GList *edges,
+				  mrptime time)
+{
+	GList             *last;
+	MrpAssignmentEdge *edge;
+
+	if (edges){
+		last = g_list_last(edges);
+		if (last){
+			edge = last->data;
+			while (time <= edge->time){
+				edges = g_list_delete_link(edges, last);
+				last = g_list_last(edges);
+				if (!last) {break;}
+				edge = last->data;
+			}
+		}
+	}
+
+	return edges;
+}
+
+/**
+ * mrp_assignment_edge_get_delta_units:
+ * @edge: a #MrpAssignmentEdge
+ *
+ * Edge-sensing function: returns the change in units associated with 
+ * an assignment, either signed positive for a start edge, or negative 
+ * for an end edge. 
+ * 
+ * Return Value: gint representing the change in assignment units at the edge.
+ **/
+gint
+mrp_assignment_edge_get_delta_units (MrpAssignmentEdge *edge)
+{		    
+	if (edge->type == START_EDGE) {
+		return edge->units;
+	} else {
+		return 0 - edge->units;
+	}
+}
Index: libplanner/mrp-assignment.h
===================================================================
--- libplanner/mrp-assignment.h	(revision 940)
+++ libplanner/mrp-assignment.h	(working copy)
@@ -3,6 +3,7 @@
  * Copyright (C) 2001-2002 CodeFactory AB
  * Copyright (C) 2001-2002 Richard Hult <richard imendio com>
  * Copyright (C) 2001-2002 Mikael Hallendal <micke imendio com>
+ * Copyright (C) 2008      Lee Baylis <lee leebaylis co uk>
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
@@ -36,6 +37,8 @@
 
 typedef struct _MrpAssignmentClass MrpAssignmentClass;
 typedef struct _MrpAssignmentPriv  MrpAssignmentPriv;
+typedef enum _MrpAssignmentEdgeType MrpAssignmentEdgeType;
+typedef struct _MrpAssignmentEdge MrpAssignmentEdge;
 
 struct _MrpAssignment {
         MrpObject          parent;
@@ -47,12 +50,36 @@
         MrpObjectClass parent_class;
 };
 
-GType              mrp_assignment_get_type     (void) G_GNUC_CONST;
+enum _MrpAssignmentEdgeType{
+        START_EDGE,
+        END_EDGE
+};
 
-MrpAssignment     *mrp_assignment_new          (void);
+struct _MrpAssignmentEdge {
+        MrpAssignmentEdgeType type;
+        mrptime time;
+        gint units;
+	gint units_in_use;
+        MrpAssignment *assignment;
+        MrpTask *task;
+};
 
-MrpTask           *mrp_assignment_get_task     (MrpAssignment *assignment);
-MrpResource       *mrp_assignment_get_resource (MrpAssignment *assignment);
-gint               mrp_assignment_get_units    (MrpAssignment *assignment);
+GType              mrp_assignment_get_type                                 (void) G_GNUC_CONST;
 
+MrpAssignment     *mrp_assignment_new                                      (void);
+
+MrpTask           *mrp_assignment_get_task                                 (MrpAssignment *assignment);
+MrpResource       *mrp_assignment_get_resource                             (MrpAssignment *assignment);
+gint               mrp_assignment_get_units                                (MrpAssignment *assignment);
+GList *            mrp_assignment_edges_insert_sorted_from_assignment      (GList *edges,
+									    MrpAssignment *assignment);
+GList *            mrp_assignment_edges_insert_sorted_from_assignment_list (GList *edges,
+							                    GList *assignments);
+GList *            mrp_assignment_edges_plot_units_in_use                  (GList *edges);
+gint               mrp_assignment_edges_calculate_max_units_in_use         (GList *edges);
+GList *            mrp_assignment_edges_remove_to_last_before              (GList *edges,
+									    mrptime time);
+GList *            mrp_assignment_edges_remove_after                       (GList *edges,
+									    mrptime time);
+gint               mrp_assignment_edge_get_delta_units                     (MrpAssignmentEdge *edge);
 #endif /* __MRP_ASSIGNMENT_H__ */
Index: libplanner/mrp-resource.c
===================================================================
--- libplanner/mrp-resource.c	(revision 940)
+++ libplanner/mrp-resource.c	(working copy)
@@ -5,6 +5,7 @@
  * Copyright (C) 2002-2003 Richard Hult <richard imendio com>
  * Copyright (C) 2002 Mikael Hallendal <micke imendio com>
  * Copyright (C) 2004 Alvaro del Castillo <acs barrapunto com>
+ * Copyright (C) 2008 Lee Baylis <lee leebaylis co uk>
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
@@ -32,6 +33,9 @@
 #include "mrp-task.h"
 #include "mrp-resource.h"
 
+/* Constant for usage calculations 
+FIXME: need to alter the UI so that users can set the priv->units value per resource, then can remove this constant */
+#define USAGE_MAX_UNITS 100
 
 struct _MrpResourcePriv {
 	gchar           *name;
@@ -69,25 +73,27 @@
 };
 
 
-static void resource_class_init            (MrpResourceClass *klass);
-static void resource_init                  (MrpResource      *resource);
-static void resource_finalize              (GObject          *object);
-static void resource_set_property          (GObject          *object,
-					    guint             prop_id,
-					    const GValue     *value,
-					    GParamSpec       *pspec);
-static void resource_get_property          (GObject          *object,
-					    guint             prop_id,
-					    GValue           *value,
-					    GParamSpec       *pspec);
-static void resource_calendar_changed      (MrpCalendar      *calendar,
-					    MrpResource      *resource);
-static void resource_removed               (MrpObject        *object);
-static void resource_invalidate_task_costs (MrpResource      *resource);
-static void resource_assignment_removed_cb (MrpAssignment    *assignment,
-					    MrpResource      *resource);
-static void resource_group_removed_cb      (MrpGroup         *group,
-					    MrpResource      *resource);
+static void   resource_class_init                  (MrpResourceClass *klass);
+static void   resource_init                        (MrpResource      *resource);
+static void   resource_finalize                    (GObject          *object);
+static void   resource_set_property                (GObject          *object,
+						    guint             prop_id,
+						    const GValue     *value,
+						    GParamSpec       *pspec);
+static void   resource_get_property                (GObject          *object,
+						    guint             prop_id,
+						    GValue           *value,
+						    GParamSpec       *pspec);
+static void   resource_calendar_changed            (MrpCalendar      *calendar,
+						    MrpResource      *resource);
+static void   resource_removed                     (MrpObject        *object);
+static void   resource_invalidate_task_costs       (MrpResource      *resource);
+static void   resource_assignment_removed_cb       (MrpAssignment    *assignment,
+						    MrpResource      *resource);
+static void   resource_group_removed_cb            (MrpGroup         *group,
+						    MrpResource      *resource);
+static GList *resource_get_edges_with_units_in_use (MrpResource      *resource, 
+						    GList            *edges);
 
 
 static MrpObjectClass *parent_class;
@@ -826,3 +832,206 @@
 
 	g_object_set (resource, "calendar", calendar, NULL);
 }
+
+/* There are two ways to look for overallocation:
+
+   - the first is to chart a running total of a resource's allocation 
+     across the whole project, and scan through it looking for total values 
+     of allocation at either a time or some condition. 
+
+     This is the technique previously adopted in planner-usage-row, 
+     now moved here and embellished upon.
+
+   - The second is to scan a resource's allocations for those which are 
+     active at a given time, and add up the usage. Whilst this is likely a 
+     more efficient method for larger projects, we are rarely interested in 
+     an individual time, more usually a period between two times, and so it 
+     is not clear right now whether implementing this second will be of any use.
+*/ 
+
+/**
+ * mrp_resource_get_assignment_edges:
+ * @resource: a #MrpResource
+ * @edges: a #GList optionally containing #MrpAssignmentEdge objects
+ *
+ * Adds all the assignment edges for the resource to the edges glist, 
+ * sorted by mrptime. Usually you want this list to be empty before 
+ * calling this function. Free the edges list when done. Mostly useful 
+ * for calculating total resource allocation over the project.
+ *
+ * Return Value: the updated edges GList
+ **/ 
+GList *
+mrp_resource_get_assignment_edges (MrpResource *resource,
+				   GList *edges)
+{
+	GList                     *assignments;
+	g_return_val_if_fail (MRP_IS_RESOURCE (resource), edges);
+
+	assignments = mrp_resource_get_assignments (resource);
+	edges = mrp_assignment_edges_insert_sorted_from_assignment_list(edges, assignments);
+
+	return edges;
+}
+
+/**
+ * mrp_resource_allocation_status:
+ * @resource: a #MrpResource
+ * @units: a #gint
+ *
+ * Lookup table for allocation status based on the number of units of a 
+ * resource which are allocated
+ *
+ * Return Value: an entry from the MrpResourceAllocation enum
+ **/
+MrpResourceAllocation
+mrp_resource_allocation_status (MrpResource *resource, gint units)
+{
+	g_return_val_if_fail (MRP_IS_RESOURCE (resource), MRP_RESOURCE_OVERALLOCATED);
+/* FIXME: replace USAGE_MAX_UNITS on a per-resource basis rather than a defined constant */
+	if (units == 0) {
+		return MRP_RESOURCE_FREE;
+	}
+	else if (units < USAGE_MAX_UNITS) {
+		return MRP_RESOURCE_UNDERALLOCATED;
+	}
+	else if (units == USAGE_MAX_UNITS) {
+		return MRP_RESOURCE_ALLOCATED;
+	} else {
+		return MRP_RESOURCE_OVERALLOCATED;
+	}
+}
+
+/**
+ * mrp_resource_test_if_overallocated:
+ * @resource: a #MrpResource
+ *
+ * Scans the project duration for the resource and determines if it is
+ * ever overallocated.
+ * 
+ * Return Value: gboolean inidcating whether resource is ever overallocated
+ **/
+gboolean 
+mrp_resource_test_if_overallocated (MrpResource *resource)
+{
+	gint units;
+
+	g_return_val_if_fail (MRP_IS_RESOURCE (resource), TRUE);
+
+	units = mrp_resource_get_max_units_used_between(resource, NULL, NULL);
+
+	if (mrp_resource_allocation_status(resource, units) == MRP_RESOURCE_OVERALLOCATED){
+		return TRUE;
+	}
+	return FALSE;
+}
+
+/**
+ * resource_get_edges_with_units_in_use:
+ * @resource: a #MrpResource
+ *
+ * Return Value: a GList of MrpAssignmentEdge objects with the running total
+ * of units in use calculated.
+ *
+ **/
+GList *
+resource_get_edges_with_units_in_use (MrpResource *resource, 
+				      GList *edges)
+{
+	g_return_val_if_fail (MRP_IS_RESOURCE (resource), edges);
+
+	edges = mrp_resource_get_assignment_edges(resource, edges);
+	edges = mrp_assignment_edges_plot_units_in_use(edges);
+
+	return edges;
+}
+
+
+/**
+ * mrp_resource_get_max_units_used_between:
+ * @resource: a #MrpResource
+ * @start: a #mrptime marking the start of a period, or project start if #NULL
+ * @end: a #mrptime marking the end of a period, or project end if #NULL
+ *
+ * Plots cumulative allocation for the resource across the project, 
+ * then scans between the start and end times given, and calculates 
+ * the maximum allocation in this period. 
+ * 
+ * Return Value: gint indicating the maximum units which have been allocated 
+ * to the resource in this period.
+ **/
+
+gint
+mrp_resource_get_max_units_used_between (MrpResource *resource, 
+					 mrptime start,
+					 mrptime end)
+{
+	GList *edges = NULL;
+	gint  units;
+
+	/* FIXME: replace USAGE_MAX_UNITS on a per-resource basis rather than a defined constant */
+	g_return_val_if_fail (MRP_IS_RESOURCE (resource), USAGE_MAX_UNITS + 1);
+
+	edges = resource_get_edges_with_units_in_use(resource, edges);
+
+	if (start){
+		edges = mrp_assignment_edges_remove_to_last_before(edges, start);
+	}
+	if (end){
+		edges = mrp_assignment_edges_remove_after(edges, end);
+	}
+
+	units = mrp_assignment_edges_calculate_max_units_in_use(edges);
+
+	g_list_free(edges);
+
+	return units;
+}
+  
+/**
+ * mrp_resource_get_available_units_between:
+ * @resource: a #MrpResource
+ * @start: a #mrptime 
+ * @end: a #mrptime
+ *
+ * Return Value: gint indicating the maximum units which are available 
+ * for the resource in this period without causing overallocation.
+ **/
+gint
+mrp_resource_get_available_units_between (MrpResource *resource,
+					  mrptime start,
+					  mrptime end)
+{
+/* FIXME: replace USAGE_MAX_UNITS on a per-resource basis rather than a defined constant */
+	g_return_val_if_fail (MRP_IS_RESOURCE (resource), -1);
+	/*	gint available;
+
+		available =*/
+	return USAGE_MAX_UNITS - mrp_resource_get_max_units_used_between(resource, start, end);
+
+	/*	if (available < 0){
+		available = 0;
+	}
+	return available;*/
+}
+
+/**
+ * mrp_resource_get_available_units_during:
+ * @resource: a #MrpResource
+ * @task: a #MrpTask 
+ *
+ * Return Value: gint indicating the maximum units which are available 
+ * for the resource between the times the task is running, without 
+ * causing overallocation.
+ **/
+gint
+mrp_resource_get_available_units_during (MrpResource *resource,
+					 MrpTask *task)
+{
+	g_return_val_if_fail (MRP_IS_RESOURCE (resource), -1);
+	g_return_val_if_fail (MRP_IS_TASK (task), -1);
+
+	return mrp_resource_get_available_units_between(resource, 
+							mrp_task_get_work_start(task), 
+							mrp_task_get_finish(task)); 
+}


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]