Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Proposal 1 #2

Draft
wants to merge 9 commits into
base: main
Choose a base branch
from
Draft

Proposal 1 #2

wants to merge 9 commits into from

Conversation

Daniel-Genkin
Copy link
Owner

@Daniel-Genkin Daniel-Genkin commented Jun 7, 2021

Work in progress

This PR presents a a proposal for a new more user optimized way of interacting with wasm.

It is not targeting dotnet/runtime as it is currently just in the planning/hypothetical stages. The new sample does not run yet.

What's changed:

I created a new browser sample that behaves equally to the already existing one but that is more explicit and more understandable. this is a proposal for how the other samples should be rewritten.

Proposed changes (mostly still in progress)

  • All JS should be in the .js files
  • Module will get renamed to DotNet via the emcc EXPORT_NAME flag for clarity (Or should DotNet be something entirely separate?)
  • User will not need to handle the initialization, loading and setup but will still have the option if needed
  • A js_support.js file exists that can be used to offload this initialization and other processes from the user (unnecessary anymore as the functionality can be contained in library_mono instead)
  • User can modify the mono configuration at runtime before it is loaded into the runtime
  • ES6 syntax is used and public API has TypeScript type annotations
  • Confusing names and inconsistent syntax are minimized
  • Methods, functions and variables will be camelCase rather than snake_case
  • The MONO, BINDING and DOTNET namespaces will merged into a single well organized and consistent namespace that will act as the exported WASM API.

To see a full list of changes you can diff with the existing browser sample as they have the same functionality

Note that since this PR was created, I have opened another one that adds TypeScript to the runtime JS files. It can be used as a reference for the types as here they are very general. dotnet#55871

@Daniel-Genkin Daniel-Genkin marked this pull request as draft June 7, 2021 19:34

DotNet.onConfigLoaded = onConfigLoaded; // optional
DotNet.onRuntimeInitialized = onRuntimeInitialized; // optional
DotNet.onMonoRuntimeInitialized = onMonoRuntimeInitialized; // required as it acts like the entry point into the program
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's make this optional too ? If undefined we could call App.init() on behalf of the user.

Copy link
Owner Author

@Daniel-Genkin Daniel-Genkin Jun 9, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

App.init is just what the old browser sample used (see further down the file). App is entirely user defined and thus not required by us for then to have. Do you think we should make it required? If so, we can make this callback optional.

I think we should keep it as is because I think it is a bit simpler and easier to understand since they have 3 callbacks instead of 3 callbacks + some mandatory object (that can't be renamed) with a mandatory function in it (that also can't be renamed) to choose from.


const App = {
init: function () {
const ret = BINDING.call_static_method("[Wasm.Browser.Sample] Sample.Test:TestMeaning", []);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

BINDING should become part of the DotNet import or separate import in DotNet.Binding.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To not pollute global namespace


// TODO find better types than the anys, however it will do for now

export interface BINDING { // Should BINDING be renamed?
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, and it should belong to DotNet namespace.
Also all the methods here should be renamed to camelCase as usual in JS.

Also I would like to understand if this is public contract or just internal API for Mono team.

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok. I also didn't yet add the library_mono.js exported functions nor those from dotnet_support.js. Perhaps I can ask this during the team meeting today.

}

// Called when MONO runtime is loaded and ready or if it errors
function onMonoRuntimeInitialized (error) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's split this. Remove the error parameter and call it only on success.
Let's have another callback onFatalError which could be called any time runtime experienced something terrible.

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This would result in 2 required callbacks. Perhaps, we should define some priorities for these changes? Currently I was just trying to make it as elegant as possible but elegant is a subjective term and not overly precise haha. So I was trying to minimize API surface area and make things explicit. Are these the only goals or are there some more as well?

Regardless, I agree with making a onFatalError callback.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

onFatalError should be optional too. default behavior console.error if not defined

configLoaded({error: "Error loading mono-config.json file from current directory"});
}
} else if (ENVIRONMENT_IS_WEB){
const xobj = new XMLHttpRequest();
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Larry made note about fetch polyfill.

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I am waiting to see the note, and other comments, before making any changes to make sure I understand what he means. However as this file is loaded before emscripten, I am not sure if the polyfill is ready yet.

};

const App = {
init: function () {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

to make clear this is user space, rename it to customInit or sampleInit

Copy link
Owner Author

@Daniel-Genkin Daniel-Genkin Jun 9, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need this App object? I kept it to stay similar to the old browser sample. However, would it be more clear to remove this object and just have a main or init function?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

in C# you mean? yes
in JS that is kind of preMain :-)

@Daniel-Genkin
Copy link
Owner Author

Should the interop.d.ts and runtime.d.ts be moved to the runtime folder?

@Daniel-Genkin
Copy link
Owner Author

Looks like currently every function in dotnet.js can be called by the samples since they are made publicly available by dotnet.js. Can we do something about this to namespace and make the API more organized? Also, these functions use snake_case but should probably be converted to use camelCase as per the usual JS convention. This could probably be done by refactoring the js files in the runtime folder but does anyone know if there is another way?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants