Browse Source

Merge branch 'programpipe' into release-1.6.3

Neal Wilson 9 years ago
parent
commit
74dd9a5566
3 changed files with 392 additions and 1 deletions
  1. 2
    0
      config/config.xml
  2. 349
    1
      src/typica.w
  3. 41
    0
      src/unsupportedserial.w

+ 2
- 0
config/config.xml View File

@@ -34,6 +34,7 @@
34 34
 	<include src="Windows/editbatchdetails.xml" />
35 35
 	<include src="Windows/newsamplebatch.xml" />
36 36
 	<program>
37
+		<![CDATA[
37 38
 		Windows = new Object();
38 39
 		var loggingWindow;
39 40
 		var currentBatchInfo;
@@ -43,5 +44,6 @@
43 44
 		var azero;
44 45
 		var bzero;
45 46
 		navwindow.windowTitle = "Typica - Choose Your Path";
47
+		]]>
46 48
 	</program>
47 49
 </application>

+ 349
- 1
src/typica.w View File

@@ -1894,6 +1894,9 @@ QScriptValue QIODevice_readToString(QScriptContext *context,
1894 1894
 QScriptValue QIODevice_putChar(QScriptContext *context, QScriptEngine *engine);
1895 1895
 QScriptValue QIODevice_writeString(QScriptContext *context, QScriptEngine *engine);
1896 1896
 QScriptValue QIODevice_writeBytes(QScriptContext *context, QScriptEngine *engine);
1897
+QScriptValue QIODevice_readBytes(QScriptContext *context, QScriptEngine *engine);
1898
+QScriptValue QIODevice_peek(QScriptContext *context, QScriptEngine *engine);
1899
+QScriptValue QIODevice_read(QScriptContext *context, QScriptEngine *engine);
1897 1900
 
1898 1901
 @ This function is passed to the scripting engine.
1899 1902
 
@@ -1948,6 +1951,9 @@ void setQIODeviceProperties(QScriptValue value, QScriptEngine *engine)
1948 1951
 	value.setProperty("putChar", engine->newFunction(QIODevice_putChar));
1949 1952
 	value.setProperty("writeString", engine->newFunction(QIODevice_writeString));
1950 1953
 	value.setProperty("writeBytes", engine->newFunction(QIODevice_writeBytes));
1954
+	value.setProperty("readBytes", engine->newFunction(QIODevice_readBytes));
1955
+	value.setProperty("peek", engine->newFunction(QIODevice_peek));
1956
+	value.setProperty("read", engine->newFunction(QIODevice_read));
1951 1957
 }
1952 1958
 
1953 1959
 @ These are simple wrappers. In the case of the |open()| property, one argument
@@ -2060,6 +2066,39 @@ QScriptValue QIODevice_writeBytes(QScriptContext *context, QScriptEngine *)
2060 2066
 	return QScriptValue();
2061 2067
 }
2062 2068
 
2069
+@ The readBytes method is an alternate wrapper around |QByteArray::readAll()|
2070
+which returns the |QByteArray| instead of converting this to a |QString|.
2071
+
2072
+@<Functions for scripting@>=
2073
+QScriptValue QIODevice_readBytes(QScriptContext *context, QScriptEngine *engine)
2074
+{
2075
+	QIODevice *self = getself<QIODevice *>(context);
2076
+	QScriptValue value = engine->toScriptValue<QByteArray>(self->readAll());
2077
+	setQByteArrayProperties(value, engine);
2078
+	return value;
2079
+}
2080
+
2081
+@ Wrappers around |peek()| and |read()| are also provided.
2082
+
2083
+@<Functions for scripting@>=
2084
+QScriptValue QIODevice_peek(QScriptContext *context, QScriptEngine *engine)
2085
+{
2086
+	QIODevice *self = getself<QIODevice *>(context);
2087
+	QScriptValue value = engine->toScriptValue<QByteArray>(
2088
+		self->peek(argument<int>(0, context)));
2089
+	setQByteArrayProperties(value, engine);
2090
+	return value;
2091
+}
2092
+
2093
+QScriptValue QIODevice_read(QScriptContext *context, QScriptEngine *engine)
2094
+{
2095
+	QIODevice *self = getself<QIODevice *>(context);
2096
+	QScriptValue value = engine->toScriptValue<QByteArray>(
2097
+		self->read(argument<int>(0, context)));
2098
+	setQByteArrayProperties(value, engine);
2099
+	return value;
2100
+}
2101
+
2063 2102
 @* Scripting QProcess.
2064 2103
 
2065 2104
 \noindent Sometimes it is useful to have \pn work with an external program.
@@ -2193,6 +2232,21 @@ void QByteArray_fromScriptValue(const QScriptValue &value, QByteArray &bytes);
2193 2232
 QScriptValue constructQByteArray(QScriptContext *context, QScriptEngine *engine);
2194 2233
 void setQByteArrayProperties(QScriptValue value, QScriptEngine *engine);
2195 2234
 QScriptValue QByteArray_fromHex(QScriptContext *context, QScriptEngine *engine);
2235
+QScriptValue QByteArray_getAt(QScriptContext *context, QScriptEngine *engine);
2236
+QScriptValue QByteArray_setAt(QScriptContext *context, QScriptEngine *engine);
2237
+QScriptValue QByteArray_appendBytes(QScriptContext *context, QScriptEngine *engine);
2238
+QScriptValue QByteArray_appendString(QScriptContext *context, QScriptEngine *engine);
2239
+QScriptValue QByteArray_size(QScriptContext *context, QScriptEngine *engine);
2240
+QScriptValue QByteArray_left(QScriptContext *context, QScriptEngine *engine);
2241
+QScriptValue QByteArray_right(QScriptContext *context, QScriptEngine *engine);
2242
+QScriptValue QByteArray_mid(QScriptContext *context, QScriptEngine *engine);
2243
+QScriptValue QByteArray_chop(QScriptContext *context, QScriptEngine *engine);
2244
+QScriptValue QByteArray_remove(QScriptContext *context, QScriptEngine *engine);
2245
+QScriptValue QByteArray_toInt8(QScriptContext *context, QScriptEngine *engine);
2246
+QScriptValue QByteArray_toInt16(QScriptContext *context, QScriptEngine *engine);
2247
+QScriptValue QByteArray_toInt32(QScriptContext *context, QScriptEngine *engine);
2248
+QScriptValue QByteArray_toFloat(QScriptContext *context, QScriptEngine *engine);
2249
+QScriptValue QByteArray_toDouble(QScriptContext *context, QScriptEngine *engine);
2196 2250
 
2197 2251
 @ First, we provide some functionns for moving array data across the
2198 2252
 language barrier.
@@ -2235,6 +2289,21 @@ want to have wrappers around. These should be added as required.
2235 2289
 void setQByteArrayProperties(QScriptValue value, QScriptEngine *engine)
2236 2290
 {
2237 2291
 	value.setProperty("fromHex", engine->newFunction(QByteArray_fromHex));
2292
+	value.setProperty("getAt", engine->newFunction(QByteArray_getAt));
2293
+	value.setProperty("setAt", engine->newFunction(QByteArray_setAt));
2294
+	value.setProperty("appendBytes", engine->newFunction(QByteArray_appendBytes));
2295
+	value.setProperty("appendString", engine->newFunction(QByteArray_appendString));
2296
+	value.setProperty("size", engine->newFunction(QByteArray_size));
2297
+	value.setProperty("left", engine->newFunction(QByteArray_left));
2298
+	value.setProperty("right", engine->newFunction(QByteArray_right));
2299
+	value.setProperty("mid", engine->newFunction(QByteArray_mid));
2300
+	value.setProperty("chop", engine->newFunction(QByteArray_chop));
2301
+	value.setProperty("remove", engine->newFunction(QByteArray_remove));
2302
+	value.setProperty("toInt8", engine->newFunction(QByteArray_toInt8));
2303
+	value.setProperty("toInt16", engine->newFunction(QByteArray_toInt16));
2304
+	value.setProperty("toInt32", engine->newFunction(QByteArray_toInt32));
2305
+	value.setProperty("toFloat", engine->newFunction(QByteArray_toFloat));
2306
+	value.setProperty("toDouble", engine->newFunction(QByteArray_toDouble));
2238 2307
 }
2239 2308
 
2240 2309
 @ Perhaps the easiest way to deal with fixed byte strings for serial
@@ -2246,7 +2315,286 @@ QScriptValue QByteArray_fromHex(QScriptContext *context, QScriptEngine *engine)
2246 2315
 	QByteArray self = getself<QByteArray>(context);
2247 2316
 	QByteArray retval;
2248 2317
 	retval = self.fromHex(argument<QString>(0, context).toUtf8());
2249
-	return engine->toScriptValue<QByteArray>(retval);
2318
+	QScriptValue value = engine->toScriptValue<QByteArray>(retval);
2319
+	setQByteArrayProperties(value, engine);
2320
+	return value;
2321
+}
2322
+
2323
+@ A pair of methods is provided for getting and setting values at a particular
2324
+byte.
2325
+
2326
+@<Functions for scripting@>=
2327
+QScriptValue QByteArray_getAt(QScriptContext *context, QScriptEngine *)
2328
+{
2329
+	QByteArray self = getself<QByteArray>(context);
2330
+	return QScriptValue((int)(self.at(argument<int>(0, context))));
2331
+}
2332
+
2333
+QScriptValue QByteArray_setAt(QScriptContext *context, QScriptEngine *)
2334
+{
2335
+	QByteArray self = getself<QByteArray>(context);
2336
+	self[argument<int>(0, context)] = (char)(argument<int>(1, context));
2337
+	return QScriptValue();
2338
+}
2339
+
2340
+@ Methods are provided for appending either another |QByteArray| or a string
2341
+to a |QByteArray|. The only difference between these functions is the expected
2342
+argument type.
2343
+
2344
+@<Functions for scripting@>=
2345
+QScriptValue QByteArray_appendBytes(QScriptContext *context, QScriptEngine *engine)
2346
+{
2347
+	QByteArray self = getself<QByteArray>(context);
2348
+	QScriptValue value =
2349
+		engine->toScriptValue<QByteArray>(
2350
+			self.append(argument<QByteArray>(0, context)));
2351
+	setQByteArrayProperties(value, engine);
2352
+	return value;
2353
+}
2354
+
2355
+QScriptValue QByteArray_appendString(QScriptContext *context, QScriptEngine *engine)
2356
+{
2357
+	QByteArray self = getself<QByteArray>(context);
2358
+	QScriptValue value = engine->toScriptValue<QByteArray>(
2359
+		self.append(argument<QString>(0, context)));
2360
+	setQByteArrayProperties(value, engine);
2361
+	return value;
2362
+}
2363
+
2364
+@ Checking the size of our byte array frequently a requirement.
2365
+
2366
+@<Functions for scripting@>=
2367
+QScriptValue QByteArray_size(QScriptContext *context, QScriptEngine *)
2368
+{
2369
+	QByteArray self = getself<QByteArray>(context);
2370
+	return QScriptValue(self.size());
2371
+}
2372
+
2373
+@ It is also frequently useful to be able to work with specific parts of a byte
2374
+array, so a few methods are provided for carving these up.
2375
+
2376
+@<Functions for scripting@>=
2377
+QScriptValue QByteArray_left(QScriptContext *context, QScriptEngine *engine)
2378
+{
2379
+	QByteArray self = getself<QByteArray>(context);
2380
+	QScriptValue value = engine->toScriptValue<QByteArray>(
2381
+		self.left(argument<int>(0, context)));
2382
+	setQByteArrayProperties(value, engine);
2383
+	return value;
2384
+}
2385
+
2386
+QScriptValue QByteArray_right(QScriptContext *context, QScriptEngine *engine)
2387
+{
2388
+	QByteArray self = getself<QByteArray>(context);
2389
+	QScriptValue value = engine->toScriptValue<QByteArray>(
2390
+		self.right(argument<int>(0, context)));
2391
+	setQByteArrayProperties(value, engine);
2392
+	return value;
2393
+}
2394
+
2395
+QScriptValue QByteArray_mid(QScriptContext *context, QScriptEngine *engine)
2396
+{
2397
+	QByteArray self = getself<QByteArray>(context);
2398
+	int length = -1;
2399
+	if(context->argumentCount() > 1)
2400
+	{
2401
+		length = argument<int>(1, context);
2402
+	}
2403
+	QScriptValue value = engine->toScriptValue<QByteArray>(
2404
+		self.mid(argument<int>(0, context), length));
2405
+	setQByteArrayProperties(value, engine);
2406
+	return value;
2407
+}
2408
+
2409
+@ We may also want to remove bytes from an array.
2410
+
2411
+@<Functions for scripting@>=
2412
+QScriptValue QByteArray_chop(QScriptContext *context, QScriptEngine *)
2413
+{
2414
+	QByteArray self = getself<QByteArray>(context);
2415
+	self.chop(argument<int>(0, context));
2416
+	return QScriptValue();
2417
+}
2418
+
2419
+QScriptValue QByteArray_remove(QScriptContext *context, QScriptEngine *engine)
2420
+{
2421
+	QByteArray self = getself<QByteArray>(context);
2422
+	QScriptValue value = engine->toScriptValue<QByteArray>(
2423
+		self.remove(argument<int>(0, context), argument<int>(1, context)));
2424
+	setQByteArrayProperties(value, engine);
2425
+	return value;
2426
+}
2427
+
2428
+@ When receiving data in a byte array, bytes are sometimes intended to
2429
+represent 8, 16, or 32 bit integers. In such cases we often want to perform
2430
+some computation on these values so having the ability to split off that
2431
+portion of the array (for example, with |mid()|) and convert to a Number is
2432
+useful.
2433
+
2434
+@<Functions for scripting@>=
2435
+QScriptValue QByteArray_toInt8(QScriptContext *context, QScriptEngine *)
2436
+{
2437
+	QByteArray self = getself<QByteArray>(context);
2438
+	int value = 0;
2439
+	char *bytes = (char *)&value;
2440
+	bytes[0] = self[0];
2441
+	return QScriptValue(value);
2442
+}
2443
+
2444
+QScriptValue QByteArray_toInt16(QScriptContext *context, QScriptEngine *)
2445
+{
2446
+	QByteArray self = getself<QByteArray>(context);
2447
+	int value = 0;
2448
+	char *bytes = (char *)&value;
2449
+	bytes[0] = self[0];
2450
+	bytes[1] = self[1];
2451
+	return QScriptValue(value);
2452
+}
2453
+
2454
+QScriptValue QByteArray_toInt32(QScriptContext *context, QScriptEngine *)
2455
+{
2456
+	QByteArray self = getself<QByteArray>(context);
2457
+	int value = 0;
2458
+	char *bytes = (char *)&value;
2459
+	bytes[0] = self[0];
2460
+	bytes[1] = self[1];
2461
+	bytes[2] = self[2];
2462
+	bytes[3] = self[3];
2463
+	return QScriptValue(value);
2464
+}
2465
+
2466
+@ Similar methods are provided for converting bytes to a |float| or |double|.
2467
+Note that the return value from |toFloat| will, in the host environment, be
2468
+represented as a |double|.
2469
+
2470
+@<Functions for scripting@>=
2471
+QScriptValue QByteArray_toFloat(QScriptContext *context, QScriptEngine *)
2472
+{
2473
+	QByteArray self = getself<QByteArray>(context);
2474
+	float value = 0.0;
2475
+	char *bytes = (char *)&value;
2476
+	bytes[0] = self[0];
2477
+	bytes[1] = self[1];
2478
+	bytes[2] = self[2];
2479
+	bytes[3] = self[3];
2480
+	return QScriptValue(value);
2481
+}
2482
+
2483
+QScriptValue QByteArray_toDouble(QScriptContext *context, QScriptEngine *)
2484
+{
2485
+	QByteArray self = getself<QByteArray>(context);
2486
+	double value = 0.0;
2487
+	char *bytes = (char *)&value;
2488
+	bytes[0] = self[0];
2489
+	bytes[1] = self[1];
2490
+	bytes[2] = self[2];
2491
+	bytes[3] = self[3];
2492
+	bytes[4] = self[4];
2493
+	bytes[5] = self[5];
2494
+	bytes[6] = self[6];
2495
+	bytes[7] = self[7];
2496
+	return QScriptValue(value);
2497
+}
2498
+
2499
+@ Some protocols require manipulating larger than 8 bit numbers as a sequence
2500
+of bytes. To facilitate this, methods are provided to construct a |QByteArray|
2501
+from different sized numbers. 8 bit numbers are provided for uniformity.
2502
+
2503
+@<Function prototypes for scripting@>=
2504
+QScriptValue bytesFromInt8(QScriptContext *context, QScriptEngine *engine);
2505
+QScriptValue bytesFromInt16(QScriptContext *context, QScriptEngine *engine);
2506
+QScriptValue bytesFromInt32(QScriptContext *context, QScriptEngine *engine);
2507
+QScriptValue bytesFromFloat(QScriptContext *context, QScriptEngine *engine);
2508
+QScriptValue bytesFromDouble(QScriptContext *context, QScriptEngine *engine);
2509
+
2510
+@ These are globally available.
2511
+
2512
+@<Set up the scripting engine@>=
2513
+engine->globalObject().setProperty("bytesFromInt8", engine->newFunction(bytesFromInt8));
2514
+engine->globalObject().setProperty("bytesFromInt16", engine->newFunction(bytesFromInt16));
2515
+engine->globalObject().setProperty("bytesFromInt32", engine->newFunction(bytesFromInt32));
2516
+engine->globalObject().setProperty("bytesFromFloat", engine->newFunction(bytesFromFloat));
2517
+engine->globalObject().setProperty("bytesFromDouble", engine->newFunction(bytesFromDouble));
2518
+
2519
+@ The methods all work by casting the appropriate numeric type to a |char *|
2520
+and copying the bytes to a new |QByteArray|. Note that the ECMA-262 standard
2521
+only has one type of number and this is an IEEE 754 binary64 double precision
2522
+floating point number. Functions other than |bytesFromDouble| will be cast
2523
+from |double|.
2524
+
2525
+@<Functions for scripting@>=
2526
+QScriptValue bytesFromInt8(QScriptContext *context, QScriptEngine *engine)
2527
+{
2528
+	qint8 value = (qint8)(argument<int>(0, context));
2529
+	char *bytes = (char *)&value;
2530
+	QByteArray retval;
2531
+	retval.resize(1);
2532
+	retval[0] = bytes[0];
2533
+	QScriptValue v = engine->toScriptValue<QByteArray>(retval);
2534
+	setQByteArrayProperties(v, engine);
2535
+	return v;
2536
+}
2537
+
2538
+QScriptValue bytesFromInt16(QScriptContext *context, QScriptEngine *engine)
2539
+{
2540
+	qint16 value = (qint16)(argument<int>(0, context));
2541
+	char *bytes = (char *)&value;
2542
+	QByteArray retval;
2543
+	retval.resize(2);
2544
+	retval[0] = bytes[0];
2545
+	retval[1] = bytes[1];
2546
+	QScriptValue v = engine->toScriptValue<QByteArray>(retval);
2547
+	setQByteArrayProperties(v, engine);
2548
+	return v;
2549
+}
2550
+
2551
+QScriptValue bytesFromInt32(QScriptContext *context, QScriptEngine *engine)
2552
+{
2553
+	qint32 value = (qint32)(argument<int>(0, context));
2554
+	char *bytes = (char *)&value;
2555
+	QByteArray retval;
2556
+	retval.resize(4);
2557
+	retval[0] = bytes[0];
2558
+	retval[1] = bytes[1];
2559
+	retval[2] = bytes[2];
2560
+	retval[3] = bytes[3];
2561
+	QScriptValue v = engine->toScriptValue<QByteArray>(retval);
2562
+	setQByteArrayProperties(v, engine);
2563
+	return v;
2564
+}
2565
+
2566
+QScriptValue bytesFromFloat(QScriptContext *context, QScriptEngine *engine)
2567
+{
2568
+	float value = (float)(argument<double>(0, context));
2569
+	char *bytes = (char *)&value;
2570
+	QByteArray retval;
2571
+	retval.resize(4);
2572
+	retval[0] = bytes[0];
2573
+	retval[1] = bytes[1];
2574
+	retval[2] = bytes[2];
2575
+	retval[3] = bytes[3];
2576
+	QScriptValue v = engine->toScriptValue<QByteArray>(retval);
2577
+	setQByteArrayProperties(v, engine);
2578
+	return v;
2579
+}
2580
+
2581
+QScriptValue bytesFromDouble(QScriptContext *context, QScriptEngine *engine)
2582
+{
2583
+	double value = (double)(argument<double>(0, context));
2584
+	char *bytes = (char *)&value;
2585
+	QByteArray retval;
2586
+	retval.resize(8);
2587
+	retval[0] = bytes[0];
2588
+	retval[1] = bytes[1];
2589
+	retval[2] = bytes[2];
2590
+	retval[3] = bytes[3];
2591
+	retval[4] = bytes[4];
2592
+	retval[5] = bytes[5];
2593
+	retval[6] = bytes[6];
2594
+	retval[7] = bytes[7];
2595
+	QScriptValue v = engine->toScriptValue<QByteArray>(retval);
2596
+	setQByteArrayProperties(v, engine);
2597
+	return v;
2250 2598
 }
2251 2599
 
2252 2600
 @* Scripting QBuffer.

+ 41
- 0
src/unsupportedserial.w View File

@@ -692,4 +692,45 @@ QScriptValue SerialPort_flush(QScriptContext *context, QScriptEngine *)
692 692
 	return QScriptValue();
693 693
 }
694 694
 
695
+@* Timers.
696
+
697
+\noindent While some devices will output a steady stream of measurements which
698
+can be continuously read as they come in, other devices must be polled for
699
+their current state. One approach is to poll the device immediately after
700
+reading the response from the previous polling, but there are times when we may
701
+want to limit the rate at which we poll the device. There are also devices
702
+which specify a length of time during which data should not be sent. For these
703
+cases, we expose |QTimer| to the host environment which allows us to wait. This
704
+is also useful for producing simulations to test features without needing to be
705
+connected to real hardware.
706
+
707
+<@Function prototypes for scripting@>=
708
+void setQTimerProperties(QScriptValue value, QScriptEngine *engine);
709
+QScriptValue constructQTimer(QScriptContext *context, QScriptEngine *engine);
710
+
711
+@ The host environment is informed of the constructor.
712
+
713
+@<Set up the scripting engine@>=
714
+constructor = engine->newFunction(constructQTimer);
715
+value = engine->newQMetaObject(&QTimer::staticMetaObject, constructor);
716
+engine->globalObject().setProperty("Timer", value);
717
+
718
+@ Everything that we are interested in here is a signal, slot, or property so
719
+there is little else to do.
720
+
721
+@<Functions for scripting@>=
722
+void setQTimerProperties(QScriptValue value, QScriptEngine *engine)
723
+{
724
+	setQObjectProperties(value, engine);
725
+}
726
+
727
+QScriptValue constructQTimer(QScriptContext *, QScriptEngine *engine)
728
+{
729
+	QScriptValue object = engine->newQObject(new QTimer);
730
+	setQTimerProperties(object, engine);
731
+	return object;
732
+}
733
+
734
+
735
+
695 736
 

Loading…
Cancel
Save