File: event.c

package info (click to toggle)
s3d 0.2.2.1-7
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 5,356 kB
  • sloc: ansic: 21,128; python: 488; perl: 98; makefile: 31; sh: 29
file content (138 lines) | stat: -rw-r--r-- 3,521 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
// SPDX-License-Identifier: LGPL-2.1-or-later
/* SPDX-FileCopyrightText: 2004-2015  Simon Wunderlich <sw@simonwunderlich.de>
 */


#include <stdint.h>                  /* for uint8_t */
#include <stdlib.h>                  /* for NULL, free */
#include "s3d.h"                     /* for s3d_evt, s3d_get_callback, etc */
#include "s3dlib.h"                  /* for s3dprintf, VLOW, etc */

static struct s3d_evt *s3d_stack;
int cb_lock = 2;  /*  callback lock */

/** \brief push event onto stack
 *
 * Pushes an event onto the event-stack. Usually you don't need to do this
 * manually.
 */
void s3d_push_event(struct s3d_evt *newevt)
{
	struct s3d_evt *p;
	s3d_cb cb;

	s3dprintf(VLOW, "pushed event %d, cb_lock = %d", newevt->event, cb_lock);
	/*  this will always be called for S3D_EVENT_NEW_OBJECT!! */
	if (newevt->event == S3D_EVENT_NEW_OBJECT) {
		_queue_new_object(*((unsigned int *)newevt->buf));
	}
	if (cb_lock == 0) { /*  no recursive event-callbacks, please! */
		if (NULL != (cb = s3d_get_callback(newevt->event))) {
			cb_lock++;   /*  on our way! lock it.. */
			cb(newevt);   /*  .. and call it! */
			cb_lock--;
			/* okay, no new callbacks, unlock now. */
			free(newevt);
			return;
		}
	}
	newevt->next = NULL;
	if (s3d_stack != NULL) {
		for (p = s3d_stack; p->next != NULL; p = p->next) { } /*  go to the end */
		p->next = newevt;
	} else
		s3d_stack = newevt;
}

/** \brief pop event from stack
 *
 * Pops the latest event from the stack. Don't forget to free() both the event
 * and its buffer! Returns a pointer to struct s3d_evt.
 */
struct s3d_evt *s3d_pop_event(void) {
	struct s3d_evt *ret;
	if ((ret = s3d_stack) != NULL)
		s3d_stack = s3d_stack->next;
	return ret;
}

/** \brief find eevnt on stack
 *
 * Finds the latest occurrence of an event, giving the event type as argument.
 * Returns a pointer to struct s3d_evt.
 */
struct s3d_evt *s3d_find_event(uint8_t event) {
	struct s3d_evt *p;
	p = s3d_stack;
	while (p != NULL) {
		if (p->event == event)
			return p;
		p = p->next;
	}
	return NULL;
}

/** \brief delete event from stack
 *
 * Deletes an event, the argument is the pointer to the event which is to be
 * deleted (maybe obtained from s3d_find_event).
 */
int s3d_delete_event(const struct s3d_evt *devt)
{
	struct s3d_evt *previous = NULL;
	struct s3d_evt *next;
	struct s3d_evt *p = s3d_stack;
	while (p != NULL) {
		/* if ((p->event==devt->event) && (p->length==devt->length)) */
		/*  if (0==memcmp(p->buf,devt->buf)) */
		next = p->next;
		if (p == devt) {
			if (p->length > 0)
				free(p->buf);
			if (previous == NULL)
				s3d_stack = p->next;  /*  the first element!! */
			else
				previous->next = p->next;  /*  unlink */

			free(p);
		} else {
			previous = p;
		}
		p = next;
	}
	return -1;
}

/** \brief process all events on stack
 *
 * This function goes through all function of the event-stack and will call
 * functions. this is useful when you define a new function but still have a lot
 * of events of this type on the stack.
 *
 * \deprecated This is probably obsolete
 */
void s3d_process_stack(void)
{
	struct s3d_evt *p;
	s3d_cb cb;
	if (cb_lock > 0) { /* can't do that now. */

		s3dprintf(VLOW, "cb_lock = %d, processing later", cb_lock);
		return;
	}
	s3dprintf(VLOW, "processing stack ...");
	while (NULL != (p = s3d_pop_event())) {
		if ((cb = s3d_get_callback(p->event)) != NULL) {
			cb_lock++;
			cb(p);
			cb_lock--;
		} else {
			/* kick out unprocessed event */

		}
		/*  free */
		if (p->length > 0)
			free(p->buf);
		free(p);
	}
}