feat(developer): Multi-process model for projects 🦕#10114
Conversation
This is a bit of an omnibus commit, apologies for that. This commit moves Keyman Developer to a proper multi-process model, where editing files from multiple projects is handled much more cleanly, with each project loaded in a separate process. Files that are edited outside of a project structure are loaded into a 'temporary project' in a single process, which provides a pathway for existing users who may have legacy files outside the normal Keyman Developer project model. There are several components to this: 1. Inter-process communication (Multiprocess, CopyDataHelper units and multiprocess test project). These modules establish a method of enumerating running Keyman Developer instances (with EnumWindow), recording relevant metadata for each instance (by thread id) in the registry (registry used because it manages contention without additional effort from us), and communicating between processes with WM_COPYDATA. 2. Command-line parsing (TikeCommandLine). Determines project ownership (ProjectOwningFile) for each filename passed on the command-line, and passes these over to existing instances of Keyman Developer that have that project loaded, or starts new instances as needed. 3. Temporary project management. Mostly in ProjectUI. Also, moved GlobalProjectStateWnd management out of ProjectFile.pas and into Project.pas, alongside other global project variables. A follow-up will add functionality to determine if a file opened within the Keyman Developer UI should open in the same instance or in a separate instance (see TfrmKeymanDeveloper.OpenFileInProject). This will use the same methodology as TikeCommandLine does now, so may involve further refactoring. This commit establishes the idea of 'keyman.kpj' as a future default filename for Keyman Developer projects, but does not enable it, in ProjectOwningFile. It is planned to introduce this fixed filename in version 18.0 (see #10113).
User Test ResultsTest specification and instructions ✅ SUITE_COMMAND_LINE: Tests involving the Keyman Developer Command Line7 tests in 1 groups PASSED
🟩 SUITE_FILE_MENU: Tests involving the File|Open menu item
Test Artifacts |
| Winapi.Windows; | ||
|
|
||
| type | ||
| TGlobalProjectStateWnd = class |
There was a problem hiding this comment.
This class is moved from Keyman.Developer.System.Project.ProjectFile.pas, to keep it together with other globals. It is otherwise unmodified.
| Result := FParent.OwnerProject; | ||
| if Result = nil then | ||
| begin | ||
| // TODO: RAISE ERROR |
There was a problem hiding this comment.
This is a lowpri item -- technically this shouldn't happen, but the fallback we have here is probably fine.
|
|
Test Results
|
In this test, the khmer_angkor.kpj file was not found, because it was not in the khmer_angkor/source folder. Even if it had been found, it seems to me likely that Keyman Developer would not have shown the Project tab. So two fixes to apply for this:
|
Refactor the file-opening code so it can be used by Keyman Developer UI as well as command-line, and then add support for opening files in per-project instances from File|Open and friends. Also moves the initialization code out of tike.dpr into Keyman.Developer.System.Main.pas, which makes it easier to maintain and read.
|
I've refactored the code to address the failing user test. This means that I think we need to re-run all the user tests, because the changes are fairly significant. I'm also going to add another test to cover the changes to the Keyman Developer File|Open menu item. Sorry @bharanidharanj! @keymanapp-test-bot retest all |
|
|
||
| kpj := TProject.Create(pt, AFilename, False); | ||
| try | ||
| kpj.Options.Version := pv10; |
There was a problem hiding this comment.
Why isn't this pv20 like in KeyboardProjectTemplate.pas?
There was a problem hiding this comment.
We use a pv10 format here because it allows us to add arbitrary files. pv20 only allows files in the project path.
@mcdurdin Shall I create a new issue for this issue (khmer_angkor.kpj file does not open using the command line)? |
No need, I've addressed the problem in this PR already 😁 Thanks! |
Test ResultsSUITE_FILE_MENU: Tests involving the File|Open menu item
|
Test ResultsSUITE_FILE_MENU: Tests involving the File|Open menu item
|
|
SUITE_FILE_MENU |
|
Changes in this pull request will be available for download in Keyman version 17.0.225-alpha |
Fixes #2761 (sorta).
Fixes #10003.
Note: does not eliminate project files altogether, because there are too many ambiguities that arose when we tried to do that. However, it should improve many aspects of project-based editing.
This is a bit of an omnibus commit, apologies for that. This commit moves Keyman Developer to a proper multi-process model, where editing files from multiple projects is handled much more cleanly, with each project loaded in a separate process.
Files that are edited outside of a project structure are loaded into a 'temporary project' in a single process, which provides a pathway for existing users who may have legacy files outside the normal Keyman Developer project model.
There are several components to this:
Also, moved GlobalProjectStateWnd management out of ProjectFile.pas and into Project.pas, alongside other global project variables.
The Keyman Developer UI also uses the same functionality to determine if a file should open in the same instance or in a separate instance (see TfrmKeymanDeveloper.OpenFilesInProject).
This commit establishes the idea of 'keyman.kpj' as a future default filename for Keyman Developer projects, but does not enable it, in ProjectOwningFile. It is planned to introduce this fixed filename in version 18.0 (see #10113).
Note: .xml also added to list of supported file types in the File|Open dialog, for LDML keyboards. This is known as a PR Rider.
User Testing
SUITE_COMMAND_LINE: Tests involving the Keyman Developer Command Line
cdto the khmer_ankgor/source folder in the keyboards repository. Try runningtike.exe khmer_angkor.kmn khmer_angkor.kps. One instance of Keyman Developer should open, with both files loaded, and it should have the title 'khmer_angkor - Keyman Developer'.tike.exe <file1.kmn> <file2.kmn> ..., where<file1.kmn>and<file2.kmn>are keyboard files from separate projects. Two instances of Keyman Developer should open, one for each file. Try various command line calls, with different .kmn, .kpj, and .kps files in each, and verify that the expected instances of Keyman Developer open.SUITE_FILE_MENU: Tests involving the File|Open menu item
Run these tests after SUITE_COMMAND_LINE; the behaviour should be largely the same as when opening files from the command line.