- Support specifying URL in loginParameters for connecting to OpenSim

- Patch some miscellaneous OpenSim related glitches
- Add waitForRegionHandshake function
- Add a concurrent promise queue
- Fix xml writing of Vector3s
- Fix asset downloading on grids without HTTP assets
- Fix buildObject to properly orientate prims
- Wrangled with CreateSelected all day and it turned out to be an OpenSim bug
- LinkFrom function for faster linking
- Updated LLSD library to fix LLMesh decoding
This commit is contained in:
Casper Warden
2020-01-07 21:01:20 +00:00
parent b248fa17ed
commit 5e235d2db1
19 changed files with 467 additions and 122 deletions

View File

@@ -3,6 +3,8 @@ import { Quaternion } from './Quaternion';
import { GlobalPosition } from './public/interfaces/GlobalPosition';
import { HTTPAssets } from '../enums/HTTPAssets';
import { Vector3 } from './Vector3';
import { Subject, Subscription } from 'rxjs';
import Timeout = NodeJS.Timeout;
export class Utils
{
@@ -450,4 +452,94 @@ export class Utils
return str.substr(0, index - 1);
}
}
static promiseConcurrent<T>(promises: (() => Promise<T>)[], concurrency: number, timeout: number): Promise<{results: T[], errors: Error[]}>
{
return new Promise<{results: T[], errors: Error[]}>(async (resolve, reject) =>
{
const originalConcurrency = concurrency;
const promiseQueue: (() => Promise<T>)[] = [];
for (const promise of promises)
{
promiseQueue.push(promise);
}
const slotAvailable: Subject<void> = new Subject<void>();
const errors: Error[] = [];
const results: T[] = [];
function waitForAvailable()
{
return new Promise<void>((resolve1, reject1) =>
{
const subs = slotAvailable.subscribe(() =>
{
subs.unsubscribe();
resolve1();
});
});
}
function runPromise(promise: () => Promise<T>)
{
concurrency--;
let timedOut = false;
let timeo: Timeout | undefined = undefined;
promise().then((result: T) =>
{
if (timedOut)
{
return;
}
if (timeo !== undefined)
{
clearTimeout(timeo);
}
results.push(result);
concurrency++;
slotAvailable.next();
}).catch((err) =>
{
if (timedOut)
{
return;
}
if (timeo !== undefined)
{
clearTimeout(timeo);
}
errors.push(err);
concurrency++;
slotAvailable.next();
});
timeo = setTimeout(() =>
{
timedOut = true;
errors.push(new Error('Promise timed out'));
concurrency++;
slotAvailable.next();
}, timeout);
}
while (promiseQueue.length > 0)
{
if (concurrency < 1)
{
await waitForAvailable();
}
else
{
const thunk = promiseQueue.shift();
if (thunk !== undefined)
{
runPromise(thunk);
}
}
}
while (concurrency < originalConcurrency)
{
await waitForAvailable();
}
resolve({results: results, errors: errors});
});
}
}