Exemple #1
0
int a3d_workq_cancel(a3d_workq_t* self, void* task)
{
	assert(self);
	assert(task);
	LOGD("debug task=%p");

	int status = A3D_WORKQ_ERROR;
	pthread_mutex_lock(&self->mutex);

	a3d_listitem_t* iter;
	if((iter = a3d_list_find(self->queue_pending, task,
	                         a3d_taskcmp_fn)) != NULL)
	{
		// cancel pending task
		a3d_workqnode_t* node;
		node = (a3d_workqnode_t*) a3d_list_remove(self->queue_pending,
		                                          &iter);
		status = node->status;
		a3d_workqnode_delete(&node);
	}
	else
	{
		while((iter = a3d_list_find(self->queue_active, task,
		                            a3d_taskcmp_fn)) != NULL)
		{
			// must wait for active task to complete
			pthread_cond_wait(&self->cond_complete, &self->mutex);
		}

		if((iter = a3d_list_find(self->queue_complete, task,
		                         a3d_taskcmp_fn)) != NULL)
		{
			// cancel completed task
			a3d_workqnode_t* node;
			node = (a3d_workqnode_t*) a3d_list_remove(self->queue_complete,
			                                          &iter);
			status = node->status;
			a3d_workqnode_delete(&node);
		}
	}

	pthread_mutex_unlock(&self->mutex);
	return status;
}
Exemple #2
0
static void naip_deleteList(void)
{
	a3d_listitem_t* iter = a3d_list_head(glist);
	while(iter)
	{
		naip_node_t* node = (naip_node_t*)
		                    a3d_list_remove(glist, &iter);
		naip_node_delete(&node);
	}
	a3d_list_delete(&glist);
}
Exemple #3
0
void a3d_textbox_clear(a3d_textbox_t* self)
{
	assert(self);
	LOGD("debug");

	a3d_listbox_t*  listbox = (a3d_listbox_t*) self;
	a3d_listitem_t* iter    = a3d_list_head(listbox->list);
	while(iter)
	{
		a3d_text_t* text;
		text = (a3d_text_t*) a3d_list_remove(listbox->list, &iter);
		a3d_text_delete(&text);
	}

	iter = a3d_list_head(self->strings);
	while(iter)
	{
		void* string = (void*) a3d_list_remove(self->strings, &iter);
		free(string);
	}

	a3d_widget_t* widget = (a3d_widget_t*) self;
	a3d_screen_dirty(widget->screen);
}
Exemple #4
0
const void* a3d_multimap_remove(a3d_multimap_t* self,
                                a3d_multimapIter_t** _iter)
{
	assert(self);
	assert(_iter);
	assert(*_iter);

	a3d_multimapIter_t* iter = *_iter;

	// remove item from list;
	a3d_list_t* list;
	list = (a3d_list_t*)
	       a3d_hashmap_val(iter->hiter);
	const void* data = a3d_list_remove(list,
	                                   &iter->item);

	// check if list is empty
	// or if next item is NULL
	if(a3d_list_empty(list))
	{
		a3d_hashmap_remove(self->hash, &iter->hiter);
		a3d_list_delete(&list);
		if(iter->hiter)
		{
			list = (a3d_list_t*)
			       a3d_hashmap_val(iter->hiter);
			iter->item = a3d_list_head(list);
		}
	}
	else if(iter->item == NULL)
	{
		iter->hiter = a3d_hashmap_next(iter->hiter);
		if(iter->hiter)
		{
			list = (a3d_list_t*)
			       a3d_hashmap_val(iter->hiter);
			iter->item = a3d_list_head(list);
		}
	}

	// check for iteration end
	if(iter->hiter == NULL)
	{
		*_iter = NULL;
	}

	return data;
}
Exemple #5
0
static int a3d_layer_fade(a3d_widget_t* widget,
                          float fade, float dt)
{
	assert(widget);
	LOGD("debug");

	int             a;
	int             animate = 0;
	a3d_layer_t*    self    = (a3d_layer_t*) widget;
	a3d_listitem_t* iter    = a3d_list_head(self->list);
	a3d_widget_t*   head    = (a3d_widget_t*)
	                          a3d_list_peekhead(self->list);
	while(iter)
	{
		widget = (a3d_widget_t*) a3d_list_peekitem(iter);
		if((self->mode == A3D_LAYER_MODE_LAYERED) ||
		   (widget == head))
		{
			a = a3d_widget_fade(widget, fade, dt);
			iter = a3d_list_next(iter);
		}
		else
		{
			// remove widget if fade-to-zero is complete
			a = a3d_widget_fade(widget, 0.0f, dt);
			if(a == 0)
			{
				a3d_list_remove(self->list, &iter);
			}
			else
			{
				iter = a3d_list_next(iter);
			}
		}
		animate |= a;
	}

	return animate;
}
Exemple #6
0
int a3d_workq_run(a3d_workq_t* self, void* task,
                  int priority)
{
	assert(self);
	assert(task);
	LOGD("debug task=%p, priority=%i", task, priority);

	pthread_mutex_lock(&self->mutex);

	// find the node containing the task or create a new one
	int status = A3D_WORKQ_ERROR;
	a3d_listitem_t*  iter = NULL;
	a3d_listitem_t*  pos  = NULL;
	a3d_workqnode_t* tmp  = NULL;
	a3d_workqnode_t* node = NULL;
	if((iter = a3d_list_find(self->queue_complete, task,
	                         a3d_taskcmp_fn)) != NULL)
	{
		// task completed
		node = (a3d_workqnode_t*) a3d_list_remove(self->queue_complete,
		                                          &iter);
		status = node->status;
		a3d_workqnode_delete(&node);
	}
	else if((iter = a3d_list_find(self->queue_active, task,
	                              a3d_taskcmp_fn)) != NULL)
	{
		node = (a3d_workqnode_t*) a3d_list_peekitem(iter);
		node->purge_id = self->purge_id;
		status = A3D_WORKQ_PENDING;
	}
	else if((iter = a3d_list_find(self->queue_pending, task,
	                              a3d_taskcmp_fn)) != NULL)
	{
		node = (a3d_workqnode_t*) a3d_list_peekitem(iter);
		node->purge_id = self->purge_id;
		if(priority > node->priority)
		{
			// move up
			pos = a3d_list_prev(iter);
			while(pos)
			{
				tmp = (a3d_workqnode_t*) a3d_list_peekitem(pos);
				if(tmp->priority >= node->priority)
				{
					break;
				}
				pos = a3d_list_prev(pos);
			}

			if(pos)
			{
				// move after pos
				a3d_list_moven(self->queue_pending, iter, pos);
			}
			else
			{
				// move to head of list
				a3d_list_move(self->queue_pending, iter, NULL);
			}
		}
		else if(priority < node->priority)
		{
			// move down
			pos = a3d_list_next(iter);
			while(pos)
			{
				tmp = (a3d_workqnode_t*) a3d_list_peekitem(pos);
				if(tmp->priority < node->priority)
				{
					break;
				}
				pos = a3d_list_next(pos);
			}

			if(pos)
			{
				// move before pos
				a3d_list_move(self->queue_pending, iter, pos);
			}
			else
			{
				// move to tail of list
				a3d_list_moven(self->queue_pending, iter, NULL);
			}
		}
		node->priority = priority;
		status = A3D_WORKQ_PENDING;
	}
	else
	{
		// create new node
		node = a3d_workqnode_new(task, self->purge_id, priority);
		if(node == NULL)
		{
			goto fail_node;
		}
		else
		{
			// find the insert position
			pos = a3d_list_tail(self->queue_pending);
			while(pos)
			{
				tmp = (a3d_workqnode_t*) a3d_list_peekitem(pos);
				if(tmp->priority >= node->priority)
				{
					break;
				}
				pos = a3d_list_prev(pos);
			}

			if(pos)
			{
				// append after pos
				if(a3d_list_append(self->queue_pending, pos,
				                   (const void*) node) == NULL)
				{
					goto fail_queue;
				}
			}
			else
			{
				// insert at head of queue
				// first item or highest priority
				if(a3d_list_insert(self->queue_pending, NULL,
				                   (const void*) node) == NULL)
				{
					goto fail_queue;
				}
			}

			status = A3D_WORKQ_PENDING;

			// wake up workq thread
			pthread_cond_signal(&self->cond_pending);
		}
	}

	pthread_mutex_unlock(&self->mutex);

	// success
	return status;

	// failure
	fail_queue:
		a3d_workqnode_delete(&node);
	fail_node:
		pthread_mutex_unlock(&self->mutex);
	return A3D_WORKQ_ERROR;
}
Exemple #7
0
void a3d_workq_purge(a3d_workq_t* self)
{
	assert(self);
	LOGD("debug");

	pthread_mutex_lock(&self->mutex);

	// purge the pending queue
	a3d_listitem_t* iter = a3d_list_head(self->queue_pending);
	while(iter)
	{
		a3d_workqnode_t* node;
		node = (a3d_workqnode_t*) a3d_list_peekitem(iter);
		if(node->purge_id != self->purge_id)
		{
			a3d_list_remove(self->queue_pending, &iter);
			(*self->purge_fn)(self->owner, node->task, node->status);
			a3d_workqnode_delete(&node);
		}
		else
		{
			iter = a3d_list_next(iter);
		}
	}

	// purge the active queue (non-blocking)
	iter = a3d_list_head(self->queue_active);
	while(iter)
	{
		a3d_workqnode_t* node;
		node = (a3d_workqnode_t*) a3d_list_peekitem(iter);
		if(node->purge_id != self->purge_id)
		{
			node->purge_id = A3D_WORKQ_PURGE;
		}
		iter = a3d_list_next(iter);
	}

	// purge the complete queue
	iter = a3d_list_head(self->queue_complete);
	while(iter)
	{
		a3d_workqnode_t* node;
		node = (a3d_workqnode_t*) a3d_list_peekitem(iter);
		if((node->purge_id != self->purge_id) ||
		   (node->purge_id == A3D_WORKQ_PURGE))
		{
			a3d_list_remove(self->queue_complete, &iter);
			(*self->purge_fn)(self->owner, node->task, node->status);
			a3d_workqnode_delete(&node);
		}
		else
		{
			iter = a3d_list_next(iter);
		}
	}

	// swap the purge id
	if(self->purge_id != A3D_WORKQ_PURGE)
	{
		self->purge_id = 1 - self->purge_id;
	}

	pthread_mutex_unlock(&self->mutex);
}
Exemple #8
0
static void a3d_textbox_reflow(a3d_widget_t* widget,
                               float w, float h)
{
	assert(widget);
	LOGD("debug w=%f, h=%f", w, h);

	a3d_textbox_t* self = (a3d_textbox_t*) widget;

	// reflow text when changes occur
	if((self->dirty  == 0) &&
	   (self->last_w == w) &&
	   (self->last_h == h))
	{
		return;
	}
	self->dirty  = 0;
	self->last_w = w;
	self->last_h = h;

	// determine maxi
	a3d_font_t* font   = a3d_screen_font(widget->screen);
	float       aspect = a3d_font_aspectRatio(font);
	float       size   = a3d_screen_layoutText(widget->screen,
	                                           self->style_text);
	int         maxi   = (int) (w/(aspect*size)) - 1;

	// maxi does not include null character
	// but max_len does
	// limit to max_len
	if((maxi >= self->max_len) ||
	   (maxi == 0))
	{
		maxi = self->max_len - 1;
	}

	// clear the text
	a3d_listbox_t*  listbox = (a3d_listbox_t*) self;
	a3d_listitem_t* iter    = a3d_list_head(listbox->list);
	while(iter)
	{
		a3d_text_t* text;
		text = (a3d_text_t*) a3d_list_remove(listbox->list, &iter);
		a3d_text_delete(&text);
	}

	// initialize parser
	char tok[256];
	char dst[256];
	int  srci = 0;
	int  toki = 0;
	int  dsti = 0;
	int  type = A3D_TOKEN_END;

	// reflow the string(s)
	iter = a3d_list_head(self->strings);
	while(iter)
	{
		const char* src = (const char*) a3d_list_peekitem(iter);

		srci = 0;
		type = getToken(src, tok, &srci, &toki);
		while(type != A3D_TOKEN_END)
		{
			if(type == A3D_TOKEN_BREAK)
			{
				if(dsti > 0)
				{
					a3d_textbox_printText(self, dst);
					a3d_textbox_printText(self, "");
				}
				else
				{
					a3d_textbox_printText(self, "");
				}
				dsti = 0;
				break;
			}

			if(dsti == 0)
			{
				strncpy(dst, tok, 256);
				dst[255] = '\0';
				dsti = toki;
			}
			else
			{
				if(dsti + toki + 1 <= maxi)
				{
					strcat(dst, " ");
					strcat(dst, tok);
					dst[255] = '\0';
					dsti += toki + 1;
				}
				else
				{
					a3d_textbox_printText(self, dst);

					strncpy(dst, tok, 256);
					dst[255] = '\0';
					dsti = toki;
				}
			}

			type = getToken(src, tok, &srci, &toki);
		}

		iter = a3d_list_next(iter);
	}

	if(dsti > 0)
	{
		a3d_textbox_printText(self, dst);
	}
}
Exemple #9
0
int a3d_multimap_add(a3d_multimap_t* self,
                     const void* val,
                     const char* key)
{
	assert(self);
	assert(val);
	assert(key);

	a3d_listitem_t* item;

	// check if the list already exists
	a3d_hashmapIter_t iter;
	a3d_list_t* list;
	list = (a3d_list_t*)
	       a3d_hashmap_find(self->hash,
	                        &iter, key);
	if(list && self->compare)
	{
		item = a3d_list_insertSorted(list,
		                             self->compare,
		                             val);
		if(item == NULL)
		{
			return 0;
		}

		return 1;
	}
	else if(list)
	{
		item = a3d_list_append(list, NULL, val);
		if(item == NULL)
		{
			return 0;
		}

		return 1;
	}

	// create a new list and add to hash
	list = a3d_list_new();
	if(list == NULL)
	{
		return 0;
	}

	item = a3d_list_append(list, NULL, val);
	if(item == NULL)
	{
		goto fail_append;
	}

	if(a3d_hashmap_add(self->hash,
	                   (const void*) list,
	                   key) == 0)
	{
		goto fail_add;
	}

	// success
	return 1;

	// failure
	fail_add:
		a3d_list_remove(list, &item);
	fail_append:
		a3d_list_delete(&list);
	return 0;
}