pojala/electrino

Remove dependencies on Foundation/Cocoa

tbodt opened this issue ยท 22 comments

tbodt commented

For portability, it would be a much better idea to use pure C/C++ instead of Objective-C wherever possible.

tbodt commented

It is possible to call Objective-C APIs from C, but the only good reason to do that is to learn about how Objective-C works. I was thinking of a platform/api agnostic backend that implements the JS apis, then some Objective-C code that connects that to the Mac APIs.

We need to start discussing about an electrino API and start implementing in C99.

Also I've some other doubts:

  • The project will target to be nodejs compatible?
  • Why we need to support HTML? I mean I've think we could add by default another template and style engines like (pug, sass, etc)
tbodt commented

@pojala has been noticeably absent from all of the github issues discussions. get in here?

I actually like how this project is very osx-native (using osx tools and libraries). It has no dependencies outside what is normally on an osx system. If you start building a generic multiplatform solution, i think you quickly end up with something huge like electron. It might be better to build a separate app using visual studio that only shares the same javascript api. The downside of course is more development work...

Maybe if we had a roadmap we could figure out which approach its better for the project

tbodt commented

@richmans A big part of what makes Electron so popular is that it's platform-independent.

In my opinion, the best way to solve this problem is to create application wrappers for each OS, and allow developers to literally drag and drop their electron application contents, change the references from electron to electrino, and their good to go.

I do agree with @richmans point about how trying to support multiple platforms will probably end up in large binary sizes.

tbodt commented

@ninjaprawn So one codebase that could be built for any given platform without including the code for other platforms? That sounds good.

Electron uses a packager to build the app for each platform, so we will end having one binary per platform.

You may have code that are platform specific in the source code, but theres also code that will be platform independent, besides that we need to write a common layer API to use in each platform and in the backend implement the platform specific code, I don't think that multiplatform code will add too much overhead to the final binary, you just could use something like this:

#if os(Linux)
import Glibc
#else
import Darwin
#endif

To solve the platform specific code, btw this its swift code but C has something similar

I've looked into the concept of having code that can be separated from the main project and that would be universally compilable. I've done this in C++, as UWP WebView on Windows (see #6) can be used within C++ code (correct me if I'm wrong). It also allows for direct exposure from native to JS, meaning we would just have to worry about macOS and Linux.

My approach for allowing for C++ -> ObjC is as follows:

  • Create the C++ Object that will have a defined structure
  • Create a class and protocol at runtime (public APIs)
  • Do some magic to overcome this issue (more to come once I polish everything)
  • And it works!

image

As far as I'm aware this would be the biggest step to getting C++ to work with Objective-C. I'm feel it would be "simple" to add some basic things such as having a universal function to add a native object to the JS environment.

tbodt commented

I was thinking of writing the apis in C, but C++ would probably be cleaner given that JS is object-oriented.

IMHO we should first define our objectives, then the implementation.

Do we want to be compatible with Electron APIs or define our own?

@kipters I think API parity with Electron should be a priority. This is from the README

Electrino is an experimental featherweight alternative to the popular and powerful Electron. It implements a minuscule portion of the APIs available in Electron, but the output app size is much smaller.

I believe the author's goal was to keep implementing more Electron APIs while keeping the size small.

Maybe @pojala should chime in?

Ok, in the readme he says he wants to implement the basic Electron APIs, starting with the ones used by stretchly

I've gathered most of the electron based APIs from stretchly:

  • ipcRenderer (.on, .send) (also ipcMain)
  • remote (.getGlobal)
  • shell (.openExternal)
  • app (.on, .makeSingleInstance, screen)
  • Tray
  • BrowserWindow (.loadURL, .webContents [.on, .send], .setAlwaysOnTop, .show)
  • globalShortcut (.register, .unregister)
  • Menu
  • dialog

Others:

  • The Notification object

We will probably also have to include Node APIs as well, since a lot of modules use them.

I would love to keep the core small so we don't need to implement the whole node APIs, just the basic ones, as a separate project.

So are you saying we should implement some the node APIs, but keep them in seperate "modules" that can be easily removed/added (like #8)?

Don't know really what API will have electrino, but to me will be better to have npm modules, instead of native modules, but we need to explore the possibilities.

@pojala Do you have any opinions on this whole discussion?

Hi all! Sorry for not replying earlier.

I really appreciate the discussion, and didn't intend any disrespect by being quiet. (I actually had my Github notifications off and simply didn't notice earlier. My side projects haven't got much interest in the past... :))

@richmans is correct about the philosophy I had in mind for this project: provide a minimum useful set of Electron-compatible APIs directly using the system-provided frameworks and the system event loop. I wrote the current JS bindings in Objective-C because that is the cleanest and most easily accessible interface to the JavaScript runtime provided on macOS. I would like to avoid adding intermediate layers such as a generalized JS binding interface.

This approach does mean that Windows and Linux ports will need to be effectively rewrites. For some of the API surface, this is not a big deal -- e.g. the BrowserWindow class is going to be mostly platform-specific code anyway, so adding an extra level of C/C++ indirection there wouldn't seem like a huge win. However, for some other APIs, much more code could be shared between platforms.

Perhaps the most useful level to implement platform-independent C/C++ layers would be within individual bindings? For example, once "fs" is implemented on the Mac, that implementation could be moved into a separate file, something like "fs_posix.c", and reused for Linux.

tbodt commented

@pojala Moving code that can be platform-independent to platform-independenc C/C++ files is essentially what I was originally proposing. I'd suggest converting the console API now, to figure out how that would work.