durable_rules 0.31.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/src/rules/state.h ADDED
@@ -0,0 +1,57 @@
1
+
2
+ #define HASH_ID 5863474
3
+ #define HASH_SID 193505797
4
+ #define UNDEFINED_INDEX 0xFFFFFFFF
5
+ #define MAX_STATE_PROPERTIES 64
6
+ #define UNDEFINED_HASH_OFFSET 0xFFFFFFFF
7
+
8
+ typedef struct jsonProperty {
9
+ unsigned int hash;
10
+ unsigned char type;
11
+ unsigned char isMaterial;
12
+ unsigned short valueOffset;
13
+ unsigned short valueLength;
14
+ unsigned short nameOffset;
15
+ unsigned short nameLength;
16
+ union {
17
+ long i;
18
+ double d;
19
+ unsigned char b;
20
+ } value;
21
+ } jsonProperty;
22
+
23
+ typedef struct stateEntry {
24
+ unsigned int nextHashOffset;
25
+ unsigned int nextLruOffset;
26
+ unsigned int prevLruOffset;
27
+ unsigned int sidHash;
28
+ unsigned int bindingIndex;
29
+ unsigned int lastRefresh;
30
+ unsigned int propertiesLength;
31
+ jsonProperty properties[MAX_STATE_PROPERTIES];
32
+ char *state;
33
+ char *sid;
34
+ } stateEntry;
35
+
36
+ unsigned int djbHash(char *str, unsigned int len);
37
+ void rehydrateProperty(jsonProperty *property, char *state);
38
+ unsigned int refreshState(void *tree, char *sid);
39
+ unsigned int constructObject(char *parentName,
40
+ char *object,
41
+ char createHashtable,
42
+ unsigned int maxProperties,
43
+ jsonProperty *properties,
44
+ unsigned int *propertiesLength,
45
+ unsigned int *midIndex,
46
+ unsigned int *sidIndex,
47
+ char **next);
48
+ unsigned int resolveBinding(void *tree,
49
+ char *sid,
50
+ void **rulesBinding);
51
+ unsigned int fetchStateProperty(void *tree,
52
+ char *sid,
53
+ unsigned int propertyHash,
54
+ unsigned int maxTime,
55
+ unsigned char ignoreStaleState,
56
+ char **state,
57
+ jsonProperty **property);
@@ -0,0 +1,37 @@
1
+ require 'mkmf'
2
+
3
+ RbConfig::MAKEFILE_CONFIG['CC'] = ENV['CC'] if ENV['CC']
4
+
5
+ rules_include = File.join(File.dirname(__FILE__), %w{.. .. src rules})
6
+ rules_lib = File.join(File.dirname(__FILE__), %w{.. .. src rules})
7
+ hiredis_lib = File.join(File.dirname(__FILE__), %w{.. .. deps hiredis})
8
+
9
+ RbConfig::CONFIG['configure_args'] =~ /with-make-prog\=(\w+)/
10
+ make_program = $1 || ENV['make']
11
+ make_program ||= case RUBY_PLATFORM
12
+ when /mswin/
13
+ 'nmake'
14
+ when /(bsd|solaris)/
15
+ 'gmake'
16
+ else
17
+ 'make'
18
+ end
19
+
20
+ # Make sure hiredis is built...
21
+ Dir.chdir(hiredis_lib) do
22
+ success = system("#{make_program} static")
23
+ raise "Building hiredis failed" if !success
24
+ end
25
+
26
+ # Make sure rules is built...
27
+ Dir.chdir(rules_lib) do
28
+ success = system("#{make_program} static")
29
+ raise "Building rules failed" if !success
30
+ end
31
+
32
+ # Statically link to hiredis (mkmf can't do this for us)
33
+ $CFLAGS << " -I#{rules_lib} "
34
+ $LDFLAGS << " #{hiredis_lib}/libhiredis.a #{rules_lib}/rules.a"
35
+
36
+ have_func("rb_thread_fd_select")
37
+ create_makefile('src/rulesrb/rules')
@@ -0,0 +1,644 @@
1
+ #include <ruby.h>
2
+ #include <rules.h>
3
+
4
+ VALUE rulesModule = Qnil;
5
+
6
+ static VALUE rbCreateRuleset(VALUE self, VALUE name, VALUE rules, VALUE stateCacheSize) {
7
+ Check_Type(name, T_STRING);
8
+ Check_Type(rules, T_STRING);
9
+
10
+ void *output = NULL;
11
+ unsigned int result = createRuleset(&output, RSTRING_PTR(name), RSTRING_PTR(rules), FIX2INT(stateCacheSize));
12
+ if (result != RULES_OK) {
13
+ if (result == ERR_OUT_OF_MEMORY) {
14
+ rb_raise(rb_eNoMemError, "Out of memory");
15
+ } else {
16
+ rb_raise(rb_eException, "Could not create ruleset, error code: %d", result);
17
+ }
18
+ }
19
+
20
+ return INT2FIX(output);
21
+ }
22
+
23
+ static VALUE rbDeleteRuleset(VALUE self, VALUE handle) {
24
+ Check_Type(handle, T_FIXNUM);
25
+
26
+ unsigned int result = deleteRuleset((void *)FIX2LONG(handle));
27
+ if (result != RULES_OK) {
28
+ if (result == ERR_OUT_OF_MEMORY) {
29
+ rb_raise(rb_eNoMemError, "Out of memory");
30
+ } else {
31
+ rb_raise(rb_eException, "Could not delete ruleset, error code: %d", result);
32
+ }
33
+ }
34
+
35
+ return Qnil;
36
+ }
37
+
38
+ static VALUE rbBindRuleset(VALUE self, VALUE handle, VALUE host, VALUE port, VALUE password) {
39
+ Check_Type(handle, T_FIXNUM);
40
+ Check_Type(host, T_STRING);
41
+ Check_Type(port, T_FIXNUM);
42
+
43
+ unsigned int result;
44
+ if (TYPE(password) == T_STRING) {
45
+ result = bindRuleset((void *)FIX2LONG(handle), RSTRING_PTR(host), FIX2INT(port), RSTRING_PTR(password));
46
+ } else if (TYPE(password) == T_NIL) {
47
+ result = bindRuleset((void *)FIX2LONG(handle), RSTRING_PTR(host), FIX2INT(port), NULL);
48
+ } else {
49
+ rb_raise(rb_eTypeError, "Wrong argument type for password");
50
+ }
51
+
52
+ if (result != RULES_OK) {
53
+ if (result == ERR_OUT_OF_MEMORY) {
54
+ rb_raise(rb_eNoMemError, "Out of memory");
55
+ } else {
56
+ rb_raise(rb_eException, "Could not create connection, error code: %d", result);
57
+ }
58
+ }
59
+
60
+ return Qnil;
61
+ }
62
+
63
+ static VALUE rbComplete(VALUE self, VALUE rulesBinding, VALUE replyCount) {
64
+ Check_Type(rulesBinding, T_FIXNUM);
65
+ Check_Type(replyCount, T_FIXNUM);
66
+
67
+ unsigned int result = complete((void *)FIX2LONG(rulesBinding), FIX2LONG(replyCount));
68
+ if (result != RULES_OK) {
69
+ if (result == ERR_OUT_OF_MEMORY) {
70
+ rb_raise(rb_eNoMemError, "Out of memory");
71
+ } else {
72
+ rb_raise(rb_eException, "Could not complete action, error code: %d", result);
73
+ }
74
+ }
75
+
76
+ return Qnil;
77
+ }
78
+
79
+ static VALUE rbStartAssertEvent(VALUE self, VALUE handle, VALUE event) {
80
+ Check_Type(handle, T_FIXNUM);
81
+ Check_Type(event, T_STRING);
82
+
83
+ unsigned int replyCount;
84
+ void *rulesBinding = NULL;
85
+ unsigned int result = startAssertEvent((void *)FIX2LONG(handle), RSTRING_PTR(event), &rulesBinding, &replyCount);
86
+ if (result == RULES_OK) {
87
+ VALUE output = rb_ary_new();
88
+ rb_ary_push(output, INT2FIX(rulesBinding));
89
+ rb_ary_push(output, INT2FIX(replyCount));
90
+ return output;
91
+ } else if (result == ERR_EVENT_NOT_HANDLED) {
92
+ VALUE output = rb_ary_new();
93
+ rb_ary_push(output, INT2FIX(0));
94
+ rb_ary_push(output, INT2FIX(0));
95
+ return output;
96
+ } else {
97
+ if (result == ERR_OUT_OF_MEMORY) {
98
+ rb_raise(rb_eNoMemError, "Out of memory");
99
+ } else {
100
+ rb_raise(rb_eException, "Could not assert event, error code: %d", result);
101
+ }
102
+ }
103
+
104
+ return Qnil;
105
+ }
106
+
107
+ static VALUE rbAssertEvent(VALUE self, VALUE handle, VALUE event) {
108
+ Check_Type(handle, T_FIXNUM);
109
+ Check_Type(event, T_STRING);
110
+
111
+ unsigned int result = assertEvent((void *)FIX2LONG(handle), RSTRING_PTR(event));
112
+ if (result == RULES_OK) {
113
+ return INT2FIX(1);
114
+ } else if (result == ERR_EVENT_NOT_HANDLED) {
115
+ return INT2FIX(0);
116
+ } else {
117
+ if (result == ERR_OUT_OF_MEMORY) {
118
+ rb_raise(rb_eNoMemError, "Out of memory");
119
+ } else {
120
+ rb_raise(rb_eException, "Could not assert event, error code: %d", result);
121
+ }
122
+ }
123
+
124
+ return Qnil;
125
+ }
126
+
127
+ static VALUE rbStartAssertEvents(VALUE self, VALUE handle, VALUE events) {
128
+ Check_Type(handle, T_FIXNUM);
129
+ Check_Type(events, T_STRING);
130
+
131
+ unsigned int *results = NULL;
132
+ unsigned int resultsLength = 0;
133
+ unsigned int replyCount;
134
+ void *rulesBinding = NULL;
135
+ unsigned int result = startAssertEvents((void *)FIX2LONG(handle), RSTRING_PTR(events), &resultsLength, &results, &rulesBinding, &replyCount);
136
+ if (result == RULES_OK) {
137
+ if (results) {
138
+ free(results);
139
+ }
140
+ VALUE output = rb_ary_new();
141
+ rb_ary_push(output, INT2FIX(rulesBinding));
142
+ rb_ary_push(output, INT2FIX(replyCount));
143
+ return output;
144
+ } else if (result == ERR_EVENT_NOT_HANDLED) {
145
+ VALUE output = rb_ary_new();
146
+ rb_ary_push(output, INT2FIX(0));
147
+ rb_ary_push(output, INT2FIX(0));
148
+ return output;
149
+ } else {
150
+ if (result == ERR_OUT_OF_MEMORY) {
151
+ rb_raise(rb_eNoMemError, "Out of memory");
152
+ } else {
153
+ if (results) {
154
+ free(results);
155
+ }
156
+ rb_raise(rb_eException, "Could not assert events, error code: %d", result);
157
+ }
158
+ }
159
+
160
+ return Qnil;
161
+ }
162
+
163
+ static VALUE rbAssertEvents(VALUE self, VALUE handle, VALUE events) {
164
+ Check_Type(handle, T_FIXNUM);
165
+ Check_Type(events, T_STRING);
166
+
167
+ unsigned int *results = NULL;
168
+ unsigned int resultsLength = 0;
169
+ unsigned int result = assertEvents((void *)FIX2LONG(handle), RSTRING_PTR(events), &resultsLength, &results);
170
+ if (result == RULES_OK) {
171
+ if (results) {
172
+ free(results);
173
+ }
174
+ return INT2FIX(resultsLength);
175
+ } else {
176
+ if (result == ERR_OUT_OF_MEMORY) {
177
+ rb_raise(rb_eNoMemError, "Out of memory");
178
+ } else {
179
+ if (results) {
180
+ free(results);
181
+ }
182
+ rb_raise(rb_eException, "Could not assert events, error code: %d", result);
183
+ }
184
+ }
185
+
186
+ return Qnil;
187
+ }
188
+
189
+ static VALUE rbRetractEvent(VALUE self, VALUE handle, VALUE event) {
190
+ Check_Type(handle, T_FIXNUM);
191
+ Check_Type(event, T_STRING);
192
+
193
+ unsigned int result = retractEvent((void *)FIX2LONG(handle), RSTRING_PTR(event));
194
+ if (result == RULES_OK) {
195
+ return INT2FIX(1);
196
+ } else if (result == ERR_EVENT_NOT_HANDLED) {
197
+ return INT2FIX(0);
198
+ } else {
199
+ if (result == ERR_OUT_OF_MEMORY) {
200
+ rb_raise(rb_eNoMemError, "Out of memory");
201
+ } else {
202
+ rb_raise(rb_eException, "Could not retract event, error code: %d", result);
203
+ }
204
+ }
205
+
206
+ return Qnil;
207
+ }
208
+
209
+ static VALUE rbStartAssertFact(VALUE self, VALUE handle, VALUE fact) {
210
+ Check_Type(handle, T_FIXNUM);
211
+ Check_Type(fact, T_STRING);
212
+
213
+ unsigned int replyCount;
214
+ void *rulesBinding = NULL;
215
+ unsigned int result = startAssertFact((void *)FIX2LONG(handle), RSTRING_PTR(fact), &rulesBinding, &replyCount);
216
+ if (result == RULES_OK) {
217
+ VALUE output = rb_ary_new();
218
+ rb_ary_push(output, INT2FIX(rulesBinding));
219
+ rb_ary_push(output, INT2FIX(replyCount));
220
+ return output;
221
+ } else if (result == ERR_EVENT_NOT_HANDLED) {
222
+ VALUE output = rb_ary_new();
223
+ rb_ary_push(output, INT2FIX(0));
224
+ rb_ary_push(output, INT2FIX(0));
225
+ return output;
226
+ } else {
227
+ if (result == ERR_OUT_OF_MEMORY) {
228
+ rb_raise(rb_eNoMemError, "Out of memory");
229
+ } else {
230
+ rb_raise(rb_eException, "Could not assert fact, error code: %d", result);
231
+ }
232
+ }
233
+
234
+ return Qnil;
235
+ }
236
+
237
+ static VALUE rbAssertFact(VALUE self, VALUE handle, VALUE fact) {
238
+ Check_Type(handle, T_FIXNUM);
239
+ Check_Type(fact, T_STRING);
240
+
241
+ unsigned int result = assertFact((void *)FIX2LONG(handle), RSTRING_PTR(fact));
242
+ if (result == RULES_OK) {
243
+ return INT2FIX(1);
244
+ } else if (result == ERR_EVENT_NOT_HANDLED) {
245
+ return INT2FIX(0);
246
+ } else {
247
+ if (result == ERR_OUT_OF_MEMORY) {
248
+ rb_raise(rb_eNoMemError, "Out of memory");
249
+ } else {
250
+ rb_raise(rb_eException, "Could not assert fact, error code: %d", result);
251
+ }
252
+ }
253
+
254
+ return Qnil;
255
+ }
256
+
257
+ static VALUE rbStartAssertFacts(VALUE self, VALUE handle, VALUE facts) {
258
+ Check_Type(handle, T_FIXNUM);
259
+ Check_Type(facts, T_STRING);
260
+
261
+ unsigned int *results = NULL;
262
+ unsigned int resultsLength = 0;
263
+ unsigned int replyCount;
264
+ void *rulesBinding = NULL;
265
+ unsigned int result = startAssertFacts((void *)FIX2LONG(handle), RSTRING_PTR(facts), &resultsLength, &results, &rulesBinding, &replyCount);
266
+ if (result == RULES_OK) {
267
+ if (results) {
268
+ free(results);
269
+ }
270
+ VALUE output = rb_ary_new();
271
+ rb_ary_push(output, INT2FIX(rulesBinding));
272
+ rb_ary_push(output, INT2FIX(replyCount));
273
+ return output;
274
+ } else if (result == ERR_EVENT_NOT_HANDLED) {
275
+ VALUE output = rb_ary_new();
276
+ rb_ary_push(output, INT2FIX(0));
277
+ rb_ary_push(output, INT2FIX(0));
278
+ return output;
279
+ } else {
280
+ if (result == ERR_OUT_OF_MEMORY) {
281
+ rb_raise(rb_eNoMemError, "Out of memory");
282
+ } else {
283
+ if (results) {
284
+ free(results);
285
+ }
286
+ rb_raise(rb_eException, "Could not assert facts, error code: %d", result);
287
+ }
288
+ }
289
+
290
+ return Qnil;
291
+ }
292
+
293
+ static VALUE rbAssertFacts(VALUE self, VALUE handle, VALUE facts) {
294
+ Check_Type(handle, T_FIXNUM);
295
+ Check_Type(facts, T_STRING);
296
+
297
+ unsigned int *results = NULL;
298
+ unsigned int resultsLength = 0;
299
+ unsigned int result = assertFacts((void *)FIX2LONG(handle), RSTRING_PTR(facts), &resultsLength, &results);
300
+ if (result == RULES_OK) {
301
+ if (results) {
302
+ free(results);
303
+ }
304
+ return INT2FIX(resultsLength);
305
+ } else {
306
+ if (result == ERR_OUT_OF_MEMORY) {
307
+ rb_raise(rb_eNoMemError, "Out of memory");
308
+ } else {
309
+ if (results) {
310
+ free(results);
311
+ }
312
+ rb_raise(rb_eException, "Could not assert facts, error code: %d", result);
313
+ }
314
+ }
315
+
316
+ return Qnil;
317
+ }
318
+
319
+ static VALUE rbStartRetractFact(VALUE self, VALUE handle, VALUE fact) {
320
+ Check_Type(handle, T_FIXNUM);
321
+ Check_Type(fact, T_STRING);
322
+
323
+ unsigned int replyCount;
324
+ void *rulesBinding = NULL;
325
+ unsigned int result = startRetractFact((void *)FIX2LONG(handle), RSTRING_PTR(fact), &rulesBinding, &replyCount);
326
+ if (result == RULES_OK) {
327
+ VALUE output = rb_ary_new();
328
+ rb_ary_push(output, INT2FIX(rulesBinding));
329
+ rb_ary_push(output, INT2FIX(replyCount));
330
+ return output;
331
+ } else if (result == ERR_EVENT_NOT_HANDLED) {
332
+ VALUE output = rb_ary_new();
333
+ rb_ary_push(output, INT2FIX(0));
334
+ rb_ary_push(output, INT2FIX(0));
335
+ return output;
336
+ } else {
337
+ if (result == ERR_OUT_OF_MEMORY) {
338
+ rb_raise(rb_eNoMemError, "Out of memory");
339
+ } else {
340
+ rb_raise(rb_eException, "Could not retract fact, error code: %d", result);
341
+ }
342
+ }
343
+
344
+ return Qnil;
345
+ }
346
+
347
+ static VALUE rbRetractFact(VALUE self, VALUE handle, VALUE fact) {
348
+ Check_Type(handle, T_FIXNUM);
349
+ Check_Type(fact, T_STRING);
350
+
351
+ unsigned int result = retractFact((void *)FIX2LONG(handle), RSTRING_PTR(fact));
352
+ if (result == RULES_OK) {
353
+ return INT2FIX(1);
354
+ } else if (result == ERR_EVENT_NOT_HANDLED) {
355
+ return INT2FIX(0);
356
+ } else {
357
+ if (result == ERR_OUT_OF_MEMORY) {
358
+ rb_raise(rb_eNoMemError, "Out of memory");
359
+ } else {
360
+ rb_raise(rb_eException, "Could not retract fact, error code: %d", result);
361
+ }
362
+ }
363
+
364
+ return Qnil;
365
+ }
366
+
367
+ static VALUE rbStartRetractFacts(VALUE self, VALUE handle, VALUE facts) {
368
+ Check_Type(handle, T_FIXNUM);
369
+ Check_Type(facts, T_STRING);
370
+
371
+ unsigned int *results = NULL;
372
+ unsigned int resultsLength = 0;
373
+ unsigned int replyCount;
374
+ void *rulesBinding = NULL;
375
+ unsigned int result = startRetractFacts((void *)FIX2LONG(handle), RSTRING_PTR(facts), &resultsLength, &results, &rulesBinding, &replyCount);
376
+ if (result == RULES_OK) {
377
+ if (results) {
378
+ free(results);
379
+ }
380
+ VALUE output = rb_ary_new();
381
+ rb_ary_push(output, INT2FIX(rulesBinding));
382
+ rb_ary_push(output, INT2FIX(replyCount));
383
+ return output;
384
+ } else if (result == ERR_EVENT_NOT_HANDLED) {
385
+ VALUE output = rb_ary_new();
386
+ rb_ary_push(output, INT2FIX(0));
387
+ rb_ary_push(output, INT2FIX(0));
388
+ return output;
389
+ } else {
390
+ if (result == ERR_OUT_OF_MEMORY) {
391
+ rb_raise(rb_eNoMemError, "Out of memory");
392
+ } else {
393
+ if (results) {
394
+ free(results);
395
+ }
396
+ rb_raise(rb_eException, "Could not retract facts, error code: %d", result);
397
+ }
398
+ }
399
+
400
+ return Qnil;
401
+ }
402
+
403
+ static VALUE rbRetractFacts(VALUE self, VALUE handle, VALUE facts) {
404
+ Check_Type(handle, T_FIXNUM);
405
+ Check_Type(facts, T_STRING);
406
+
407
+ unsigned int *results = NULL;
408
+ unsigned int resultsLength = 0;
409
+ unsigned int result = retractFacts((void *)FIX2LONG(handle), RSTRING_PTR(facts), &resultsLength, &results);
410
+ if (result == RULES_OK) {
411
+ if (results) {
412
+ free(results);
413
+ }
414
+ return INT2FIX(resultsLength);
415
+ } else {
416
+ if (result == ERR_OUT_OF_MEMORY) {
417
+ rb_raise(rb_eNoMemError, "Out of memory");
418
+ } else {
419
+ if (results) {
420
+ free(results);
421
+ }
422
+ rb_raise(rb_eException, "Could not retract facts, error code: %d", result);
423
+ }
424
+ }
425
+
426
+ return Qnil;
427
+ }
428
+
429
+ static VALUE rbAssertState(VALUE self, VALUE handle, VALUE state) {
430
+ Check_Type(handle, T_FIXNUM);
431
+ Check_Type(state, T_STRING);
432
+
433
+ unsigned int result = assertState((void *)FIX2LONG(handle), RSTRING_PTR(state));
434
+ if (result == RULES_OK) {
435
+ return INT2FIX(1);
436
+ } else if (result == ERR_EVENT_NOT_HANDLED) {
437
+ return INT2FIX(0);
438
+ } else {
439
+ if (result == ERR_OUT_OF_MEMORY) {
440
+ rb_raise(rb_eNoMemError, "Out of memory");
441
+ } else {
442
+ rb_raise(rb_eException, "Could not assert event, error code: %d", result);
443
+ }
444
+ }
445
+
446
+ return Qnil;
447
+ }
448
+
449
+ static VALUE rbStartUpdateState(VALUE self, VALUE handle, VALUE actionHandle, VALUE state) {
450
+ Check_Type(handle, T_FIXNUM);
451
+ Check_Type(actionHandle, T_FIXNUM);
452
+ Check_Type(state, T_STRING);
453
+
454
+ unsigned int replyCount;
455
+ void *rulesBinding = NULL;
456
+ unsigned int result = startUpdateState((void *)FIX2LONG(handle), (void *)FIX2LONG(actionHandle), RSTRING_PTR(state), &rulesBinding, &replyCount);
457
+ if (result == RULES_OK) {
458
+ VALUE output = rb_ary_new();
459
+ rb_ary_push(output, INT2FIX(rulesBinding));
460
+ rb_ary_push(output, INT2FIX(replyCount));
461
+ return output;
462
+ } else if (result == ERR_EVENT_NOT_HANDLED) {
463
+ VALUE output = rb_ary_new();
464
+ rb_ary_push(output, INT2FIX(0));
465
+ rb_ary_push(output, INT2FIX(0));
466
+ return output;
467
+ } else {
468
+ if (result == ERR_OUT_OF_MEMORY) {
469
+ rb_raise(rb_eNoMemError, "Out of memory");
470
+ } else {
471
+ rb_raise(rb_eException, "Could not start update state, error code: %d", result);
472
+ }
473
+ }
474
+
475
+ return Qnil;
476
+ }
477
+
478
+ static VALUE rbStartAction(VALUE self, VALUE handle) {
479
+ Check_Type(handle, T_FIXNUM);
480
+
481
+ char *state;
482
+ char *messages;
483
+ void *actionHandle;
484
+ void *actionBinding;
485
+ unsigned int result = startAction((void *)FIX2LONG(handle), &state, &messages, &actionHandle, &actionBinding);
486
+ if (result == ERR_NO_ACTION_AVAILABLE) {
487
+ return Qnil;
488
+ } else if (result != RULES_OK) {
489
+ if (result == ERR_OUT_OF_MEMORY) {
490
+ rb_raise(rb_eNoMemError, "Out of memory");
491
+ } else {
492
+ rb_raise(rb_eException, "Could not start action, error code: %d", result);
493
+ }
494
+ }
495
+
496
+ VALUE output = rb_ary_new();
497
+ rb_ary_push(output, rb_str_new2(state));
498
+ rb_ary_push(output, rb_str_new2(messages));
499
+ rb_ary_push(output, INT2FIX(actionHandle));
500
+ rb_ary_push(output, INT2FIX(actionBinding));
501
+ return output;
502
+ }
503
+
504
+ static VALUE rbCompleteAction(VALUE self, VALUE handle, VALUE actionHandle, VALUE state) {
505
+ Check_Type(handle, T_FIXNUM);
506
+ Check_Type(actionHandle, T_FIXNUM);
507
+ Check_Type(state, T_STRING);
508
+
509
+ unsigned int result = completeAction((void *)FIX2LONG(handle), (void *)FIX2LONG(actionHandle), RSTRING_PTR(state));
510
+ if (result != RULES_OK) {
511
+ if (result == ERR_OUT_OF_MEMORY) {
512
+ rb_raise(rb_eNoMemError, "Out of memory");
513
+ } else {
514
+ rb_raise(rb_eException, "Could not complete action, error code: %d", result);
515
+ }
516
+ }
517
+
518
+ return Qnil;
519
+ }
520
+
521
+ static VALUE rbCompleteAndStartAction(VALUE self, VALUE handle, VALUE expectedReplies, VALUE actionHandle) {
522
+ Check_Type(handle, T_FIXNUM);
523
+ Check_Type(expectedReplies, T_FIXNUM);
524
+ Check_Type(actionHandle, T_FIXNUM);
525
+
526
+ char *messages;
527
+ unsigned int result = completeAndStartAction((void *)FIX2LONG(handle), FIX2LONG(expectedReplies), (void *)FIX2LONG(actionHandle), &messages);
528
+ if (result == ERR_NO_ACTION_AVAILABLE) {
529
+ return Qnil;
530
+ } else if (result != RULES_OK) {
531
+ if (result == ERR_OUT_OF_MEMORY) {
532
+ rb_raise(rb_eNoMemError, "Out of memory");
533
+ } else {
534
+ rb_raise(rb_eException, "Could not complete and start action, error code: %d", result);
535
+ }
536
+ }
537
+
538
+ return rb_str_new2(messages);
539
+ }
540
+
541
+
542
+ static VALUE rbAbandonAction(VALUE self, VALUE handle, VALUE actionHandle) {
543
+ Check_Type(handle, T_FIXNUM);
544
+ Check_Type(actionHandle, T_FIXNUM);
545
+
546
+ unsigned int result = abandonAction((void *)FIX2LONG(handle), (void *)FIX2LONG(actionHandle));
547
+ if (result != RULES_OK) {
548
+ if (result == ERR_OUT_OF_MEMORY) {
549
+ rb_raise(rb_eNoMemError, "Out of memory");
550
+ } else {
551
+ rb_raise(rb_eException, "Could not abandon action, error code: %d", result);
552
+ }
553
+ }
554
+
555
+ return Qnil;
556
+ }
557
+
558
+ static VALUE rbStartTimer(VALUE self, VALUE handle, VALUE sid, VALUE duration, VALUE timer) {
559
+ Check_Type(handle, T_FIXNUM);
560
+ Check_Type(sid, T_STRING);
561
+ Check_Type(duration, T_FIXNUM);
562
+ Check_Type(timer, T_STRING);
563
+
564
+ unsigned int result = startTimer((void *)FIX2LONG(handle), RSTRING_PTR(sid), FIX2UINT(duration), RSTRING_PTR(timer));
565
+ if (result != RULES_OK) {
566
+ if (result == ERR_OUT_OF_MEMORY) {
567
+ rb_raise(rb_eNoMemError, "Out of memory");
568
+ } else {
569
+ rb_raise(rb_eException, "Could not start timer, error code: %d", result);
570
+ }
571
+ }
572
+
573
+ return Qnil;
574
+ }
575
+
576
+ static VALUE rbAssertTimers(VALUE self, VALUE handle) {
577
+ Check_Type(handle, T_FIXNUM);
578
+
579
+ unsigned int result = assertTimers((void *)FIX2LONG(handle));
580
+ if (result == RULES_OK) {
581
+ return INT2FIX(1);
582
+ } else if (result == ERR_NO_TIMERS_AVAILABLE) {
583
+ return INT2FIX(0);
584
+ } else {
585
+ if (result == ERR_OUT_OF_MEMORY) {
586
+ rb_raise(rb_eNoMemError, "Out of memory");
587
+ } else {
588
+ rb_raise(rb_eException, "Could not assert timers, error code: %d", result);
589
+ }
590
+ }
591
+
592
+ return Qnil;
593
+ }
594
+
595
+ static VALUE rbGetState(VALUE self, VALUE handle, VALUE sid) {
596
+ Check_Type(handle, T_FIXNUM);
597
+ Check_Type(sid, T_STRING);
598
+
599
+ char *state;
600
+ unsigned int result = getState((void *)FIX2LONG(handle), RSTRING_PTR(sid), &state);
601
+ if (result != RULES_OK) {
602
+ if (result == ERR_OUT_OF_MEMORY) {
603
+ rb_raise(rb_eNoMemError, "Out of memory");
604
+ } else {
605
+ rb_raise(rb_eException, "Could not get state, error code: %d", result);
606
+ }
607
+ }
608
+
609
+ VALUE output = rb_str_new2(state);
610
+ free(state);
611
+ return output;
612
+ }
613
+
614
+ void Init_rules() {
615
+ rulesModule = rb_define_module("Rules");
616
+ rb_define_singleton_method(rulesModule, "create_ruleset", rbCreateRuleset, 3);
617
+ rb_define_singleton_method(rulesModule, "delete_ruleset", rbDeleteRuleset, 1);
618
+ rb_define_singleton_method(rulesModule, "bind_ruleset", rbBindRuleset, 4);
619
+ rb_define_singleton_method(rulesModule, "complete", rbComplete, 2);
620
+ rb_define_singleton_method(rulesModule, "assert_event", rbAssertEvent, 2);
621
+ rb_define_singleton_method(rulesModule, "start_assert_event", rbStartAssertEvent, 2);
622
+ rb_define_singleton_method(rulesModule, "assert_events", rbAssertEvents, 2);
623
+ rb_define_singleton_method(rulesModule, "start_assert_events", rbStartAssertEvents, 2);
624
+ rb_define_singleton_method(rulesModule, "retract_event", rbRetractEvent, 2);
625
+ rb_define_singleton_method(rulesModule, "start_assert_fact", rbStartAssertFact, 2);
626
+ rb_define_singleton_method(rulesModule, "assert_fact", rbAssertFact, 2);
627
+ rb_define_singleton_method(rulesModule, "start_assert_facts", rbStartAssertFacts, 2);
628
+ rb_define_singleton_method(rulesModule, "assert_facts", rbAssertFacts, 2);
629
+ rb_define_singleton_method(rulesModule, "start_retract_fact", rbStartRetractFact, 2);
630
+ rb_define_singleton_method(rulesModule, "retract_fact", rbRetractFact, 2);
631
+ rb_define_singleton_method(rulesModule, "start_retract_facts", rbStartRetractFacts, 2);
632
+ rb_define_singleton_method(rulesModule, "retract_facts", rbRetractFacts, 2);
633
+ rb_define_singleton_method(rulesModule, "assert_state", rbAssertState, 2);
634
+ rb_define_singleton_method(rulesModule, "start_update_state", rbStartUpdateState, 3);
635
+ rb_define_singleton_method(rulesModule, "start_action", rbStartAction, 1);
636
+ rb_define_singleton_method(rulesModule, "complete_action", rbCompleteAction, 3);
637
+ rb_define_singleton_method(rulesModule, "complete_and_start_action", rbCompleteAndStartAction, 3);
638
+ rb_define_singleton_method(rulesModule, "abandon_action", rbAbandonAction, 2);
639
+ rb_define_singleton_method(rulesModule, "start_timer", rbStartTimer, 4);
640
+ rb_define_singleton_method(rulesModule, "assert_timers", rbAssertTimers, 1);
641
+ rb_define_singleton_method(rulesModule, "get_state", rbGetState, 2);
642
+ }
643
+
644
+