web: Make `SourceAPI` a singleton
As a first step towards a simpler Web API, convert `SourceAPI` from a class to a constant object, under the assumption that `SourceAPI` isn't a public Ruffle API and as such is safe to be changed. As a result the different `ruffle-core` users don't need to construct a new `SourceAPI` instance before calling `PublicAPI.negotiate()`.
This commit is contained in:
parent
8d30833d02
commit
1accf2d8f9
|
@ -9,7 +9,6 @@ export * from "./ruffle-imports";
|
||||||
export * from "./ruffle-object";
|
export * from "./ruffle-object";
|
||||||
export * from "./ruffle-player";
|
export * from "./ruffle-player";
|
||||||
export * from "./shadow-template";
|
export * from "./shadow-template";
|
||||||
export * from "./source-api";
|
|
||||||
export * from "./version";
|
export * from "./version";
|
||||||
export * from "./version-range";
|
export * from "./version-range";
|
||||||
export * from "./config";
|
export * from "./config";
|
||||||
|
|
|
@ -32,7 +32,7 @@ export class PublicAPI {
|
||||||
*/
|
*/
|
||||||
config: Config;
|
config: Config;
|
||||||
|
|
||||||
private sources: Record<string, SourceAPI>;
|
private sources: Record<string, typeof SourceAPI>;
|
||||||
private invoked: boolean;
|
private invoked: boolean;
|
||||||
private newestName: string | null;
|
private newestName: string | null;
|
||||||
private conflict: Record<string, unknown> | null;
|
private conflict: Record<string, unknown> | null;
|
||||||
|
@ -111,11 +111,9 @@ export class PublicAPI {
|
||||||
* Register a given source with the Ruffle Public API.
|
* Register a given source with the Ruffle Public API.
|
||||||
*
|
*
|
||||||
* @param name The name of the source.
|
* @param name The name of the source.
|
||||||
* @param api The public API object. This must conform to the shape
|
|
||||||
* of `SourceAPI`.
|
|
||||||
*/
|
*/
|
||||||
registerSource(name: string, api: SourceAPI): void {
|
registerSource(name: string): void {
|
||||||
this.sources[name] = api;
|
this.sources[name] = SourceAPI;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -172,7 +170,7 @@ export class PublicAPI {
|
||||||
*
|
*
|
||||||
* @returns An instance of the Source API.
|
* @returns An instance of the Source API.
|
||||||
*/
|
*/
|
||||||
newest(): SourceAPI | null {
|
newest(): typeof SourceAPI | null {
|
||||||
const name = this.newestSourceName();
|
const name = this.newestSourceName();
|
||||||
return name !== null ? this.sources[name] : null;
|
return name !== null ? this.sources[name] : null;
|
||||||
}
|
}
|
||||||
|
@ -186,7 +184,7 @@ export class PublicAPI {
|
||||||
* @returns An instance of the Source API, if one or more
|
* @returns An instance of the Source API, if one or more
|
||||||
* sources satisfied the requirement.
|
* sources satisfied the requirement.
|
||||||
*/
|
*/
|
||||||
satisfying(ver_requirement: string): SourceAPI | null {
|
satisfying(ver_requirement: string): typeof SourceAPI | null {
|
||||||
const requirement = VersionRange.fromRequirementString(ver_requirement);
|
const requirement = VersionRange.fromRequirementString(ver_requirement);
|
||||||
let valid = null;
|
let valid = null;
|
||||||
|
|
||||||
|
@ -209,7 +207,7 @@ export class PublicAPI {
|
||||||
*
|
*
|
||||||
* @returns An instance of the Source API
|
* @returns An instance of the Source API
|
||||||
*/
|
*/
|
||||||
localCompatible(): SourceAPI | null {
|
localCompatible(): typeof SourceAPI | null {
|
||||||
if (this.sources.local !== undefined) {
|
if (this.sources.local !== undefined) {
|
||||||
return this.satisfying("^" + this.sources.local.version);
|
return this.satisfying("^" + this.sources.local.version);
|
||||||
} else {
|
} else {
|
||||||
|
@ -223,7 +221,7 @@ export class PublicAPI {
|
||||||
*
|
*
|
||||||
* @returns An instance of the Source API
|
* @returns An instance of the Source API
|
||||||
*/
|
*/
|
||||||
local(): SourceAPI | null {
|
local(): typeof SourceAPI | null {
|
||||||
if (this.sources.local !== undefined) {
|
if (this.sources.local !== undefined) {
|
||||||
return this.satisfying("=" + this.sources.local.version);
|
return this.satisfying("=" + this.sources.local.version);
|
||||||
} else {
|
} else {
|
||||||
|
@ -263,7 +261,6 @@ export class PublicAPI {
|
||||||
* version of Ruffle, since there is no Public API to upgrade from.
|
* version of Ruffle, since there is no Public API to upgrade from.
|
||||||
* @param sourceName The name of this particular
|
* @param sourceName The name of this particular
|
||||||
* Ruffle source.
|
* Ruffle source.
|
||||||
* @param sourceAPI The Ruffle source to add.
|
|
||||||
*
|
*
|
||||||
* If both parameters are provided they will be used to define a new Ruffle
|
* If both parameters are provided they will be used to define a new Ruffle
|
||||||
* source to register with the public API.
|
* source to register with the public API.
|
||||||
|
@ -271,8 +268,7 @@ export class PublicAPI {
|
||||||
*/
|
*/
|
||||||
static negotiate(
|
static negotiate(
|
||||||
prevRuffle: PublicAPI | null | Record<string, unknown>,
|
prevRuffle: PublicAPI | null | Record<string, unknown>,
|
||||||
sourceName: string | undefined,
|
sourceName: string | undefined
|
||||||
sourceAPI: SourceAPI | undefined
|
|
||||||
): PublicAPI {
|
): PublicAPI {
|
||||||
let publicAPI: PublicAPI;
|
let publicAPI: PublicAPI;
|
||||||
if (prevRuffle instanceof PublicAPI) {
|
if (prevRuffle instanceof PublicAPI) {
|
||||||
|
@ -281,8 +277,8 @@ export class PublicAPI {
|
||||||
publicAPI = new PublicAPI(prevRuffle);
|
publicAPI = new PublicAPI(prevRuffle);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sourceName !== undefined && sourceAPI !== undefined) {
|
if (sourceName !== undefined) {
|
||||||
publicAPI.registerSource(sourceName, sourceAPI);
|
publicAPI.registerSource(sourceName);
|
||||||
|
|
||||||
// Install the faux plugin detection immediately.
|
// Install the faux plugin detection immediately.
|
||||||
// This is necessary because scripts such as SWFObject check for the
|
// This is necessary because scripts such as SWFObject check for the
|
||||||
|
@ -290,7 +286,7 @@ export class PublicAPI {
|
||||||
// TODO: Maybe there's a better place for this.
|
// TODO: Maybe there's a better place for this.
|
||||||
const polyfills = publicAPI.config.polyfills;
|
const polyfills = publicAPI.config.polyfills;
|
||||||
if (polyfills !== false) {
|
if (polyfills !== false) {
|
||||||
sourceAPI.pluginPolyfill();
|
SourceAPI.pluginPolyfill();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,28 +10,11 @@ import { RufflePlayer } from "./ruffle-player";
|
||||||
* negotiator (see [[PublicAPI]]) what this particular version of Ruffle is and
|
* negotiator (see [[PublicAPI]]) what this particular version of Ruffle is and
|
||||||
* how to control it.
|
* how to control it.
|
||||||
*/
|
*/
|
||||||
export class SourceAPI {
|
export const SourceAPI = {
|
||||||
private name: string;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Construct a Source API.
|
* The version of this particular API, as a string in a semver compatible format.
|
||||||
*
|
|
||||||
* @param name The name of this particular source.
|
|
||||||
*/
|
*/
|
||||||
constructor(name: string) {
|
version: "%VERSION_NUMBER%",
|
||||||
this.name = name;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The version of this particular API.
|
|
||||||
*
|
|
||||||
* This is returned as a string in a semver compatible format.
|
|
||||||
*
|
|
||||||
* @returns The version of this Ruffle source
|
|
||||||
*/
|
|
||||||
get version(): string {
|
|
||||||
return "%VERSION_NUMBER%";
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Start up the polyfills.
|
* Start up the polyfills.
|
||||||
|
@ -42,7 +25,7 @@ export class SourceAPI {
|
||||||
*/
|
*/
|
||||||
polyfill(isExt: boolean): void {
|
polyfill(isExt: boolean): void {
|
||||||
polyfill(isExt);
|
polyfill(isExt);
|
||||||
}
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Polyfill the plugin detection.
|
* Polyfill the plugin detection.
|
||||||
|
@ -51,7 +34,7 @@ export class SourceAPI {
|
||||||
*/
|
*/
|
||||||
pluginPolyfill(): void {
|
pluginPolyfill(): void {
|
||||||
pluginPolyfill();
|
pluginPolyfill();
|
||||||
}
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a Ruffle player element using this particular version of Ruffle.
|
* Create a Ruffle player element using this particular version of Ruffle.
|
||||||
|
@ -62,5 +45,5 @@ export class SourceAPI {
|
||||||
createPlayer(): RufflePlayer {
|
createPlayer(): RufflePlayer {
|
||||||
const name = registerElement("ruffle-player", RufflePlayer);
|
const name = registerElement("ruffle-player", RufflePlayer);
|
||||||
return <RufflePlayer>document.createElement(name);
|
return <RufflePlayer>document.createElement(name);
|
||||||
}
|
},
|
||||||
}
|
};
|
||||||
|
|
|
@ -1,12 +1,8 @@
|
||||||
import "./index.css";
|
import "./index.css";
|
||||||
|
|
||||||
import { SourceAPI, PublicAPI } from "ruffle-core";
|
import { PublicAPI } from "ruffle-core";
|
||||||
|
|
||||||
window.RufflePlayer = PublicAPI.negotiate(
|
window.RufflePlayer = PublicAPI.negotiate(window.RufflePlayer, "local");
|
||||||
window.RufflePlayer,
|
|
||||||
"local",
|
|
||||||
new SourceAPI("local")
|
|
||||||
);
|
|
||||||
const ruffle = window.RufflePlayer.newest();
|
const ruffle = window.RufflePlayer.newest();
|
||||||
|
|
||||||
let player;
|
let player;
|
||||||
|
|
|
@ -1,11 +1,7 @@
|
||||||
import * as utils from "./utils";
|
import * as utils from "./utils";
|
||||||
import { PublicAPI, SourceAPI, Letterbox } from "ruffle-core";
|
import { PublicAPI, Letterbox } from "ruffle-core";
|
||||||
|
|
||||||
const api = PublicAPI.negotiate(
|
const api = PublicAPI.negotiate(window.RufflePlayer!, "local");
|
||||||
window.RufflePlayer!,
|
|
||||||
"local",
|
|
||||||
new SourceAPI("local")
|
|
||||||
);
|
|
||||||
window.RufflePlayer = api;
|
window.RufflePlayer = api;
|
||||||
const ruffle = api.newest()!;
|
const ruffle = api.newest()!;
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { PublicAPI, SourceAPI, Config } from "ruffle-core";
|
import { PublicAPI, Config } from "ruffle-core";
|
||||||
|
|
||||||
interface LoadMessage {
|
interface LoadMessage {
|
||||||
type: "load";
|
type: "load";
|
||||||
|
@ -21,8 +21,7 @@ function handleMessage(message: Message) {
|
||||||
};
|
};
|
||||||
window.RufflePlayer = PublicAPI.negotiate(
|
window.RufflePlayer = PublicAPI.negotiate(
|
||||||
window.RufflePlayer!,
|
window.RufflePlayer!,
|
||||||
"extension",
|
"extension"
|
||||||
new SourceAPI("extension")
|
|
||||||
);
|
);
|
||||||
return {};
|
return {};
|
||||||
case "ping":
|
case "ping":
|
||||||
|
|
|
@ -1,7 +1,3 @@
|
||||||
import { PublicAPI, SourceAPI } from "ruffle-core";
|
import { PublicAPI } from "ruffle-core";
|
||||||
|
|
||||||
window.RufflePlayer = PublicAPI.negotiate(
|
window.RufflePlayer = PublicAPI.negotiate(window.RufflePlayer, "local");
|
||||||
window.RufflePlayer,
|
|
||||||
"local",
|
|
||||||
new SourceAPI("local")
|
|
||||||
);
|
|
||||||
|
|
Loading…
Reference in New Issue