-
Notifications
You must be signed in to change notification settings - Fork 34
Create new project action in searcher. #1566
Changes from 5 commits
074aefe
ca89039
c44ad20
ec93597
1be198c
1b11b70
6df60f5
99f32f1
9a65231
679d654
a0ee9e5
589a403
5148154
58b10ec
b929f64
75d5366
384b9a0
b675ee4
ab849cb
245c21f
84921d7
a58d8bc
9b9c14d
ccda769
c264a2c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
pub mod desktop; | ||
pub mod cloud; | ||
|
||
use crate::prelude::*; | ||
|
||
use crate::notification; | ||
|
||
|
||
|
||
// ============================ | ||
// === Status Notifications === | ||
// ============================ | ||
|
||
pub type ProcessHandle = usize; | ||
|
||
#[derive(Clone,Debug)] | ||
pub enum StatusNotification { | ||
Event { label:String }, | ||
ProcessStarted { label:String, handle:ProcessHandle }, | ||
ProcessFinished { handle:ProcessHandle }, | ||
} | ||
|
||
#[derive(Clone,CloneRef,Debug,Default)] | ||
pub struct StatusNotifications { | ||
publisher : notification::Publisher<StatusNotification>, | ||
next_process_handle : Rc<Cell<usize>>, | ||
} | ||
|
||
impl StatusNotifications { | ||
pub fn new() -> Self { default() } | ||
|
||
pub fn publish_event(&self, label:impl Into<String>) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'd bikeshed a few more names here. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I dont understand this comment |
||
let label = label.into(); | ||
let notification = StatusNotification::Event {label}; | ||
executor::global::spawn(self.publisher.publish(notification)); | ||
} | ||
|
||
pub fn publish_process(&self, label:impl Into<String>) -> ProcessHandle { | ||
let label = label.into(); | ||
let handle = self.next_process_handle.get(); | ||
self.next_process_handle.set(handle + 1); | ||
let notification = StatusNotification::ProcessStarted {label,handle}; | ||
executor::global::spawn(self.publisher.publish(notification)); | ||
handle | ||
} | ||
|
||
pub fn published_process_finished(&self, handle:ProcessHandle) { | ||
let notification = StatusNotification::ProcessFinished {handle}; | ||
executor::global::spawn(self.publisher.publish(notification)); | ||
} | ||
|
||
pub fn subscribe(&self) -> impl Stream<Item=StatusNotification> { | ||
self.publisher.subscribe() | ||
} | ||
} | ||
|
||
// ==================== | ||
// === Notification === | ||
// ==================== | ||
|
||
#[derive(Copy,Clone,Debug)] | ||
pub enum Notification { | ||
NewProjectCreated | ||
} | ||
|
||
|
||
|
||
// =========== | ||
// === API === | ||
// =========== | ||
|
||
pub trait ManagingProjectAPI { | ||
fn create_new_project<'a>(&'a self) -> BoxFuture<'a, FallibleResult>; | ||
} | ||
|
||
pub trait API:Debug { | ||
fn current_project(&self) -> model::Project; | ||
|
||
fn status_notifications(&self) -> &StatusNotifications; | ||
|
||
fn subscribe(&self) -> StaticBoxStream<Notification>; | ||
|
||
fn manage_projects(&self) -> Option<&dyn ManagingProjectAPI>; | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Perhaps IDE should also provide parser? |
||
|
||
pub type Handle = Rc<dyn API>; | ||
pub type Desktop = desktop::Handle; | ||
pub type Cloud = cloud::Handle; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
use crate::prelude::*; | ||
use crate::controller::ide::{ManagingProjectAPI, Notification}; | ||
use crate::controller::ide::StatusNotifications; | ||
|
||
use enso_protocol::project_manager::ProjectName; | ||
use flo_stream::Subscriber; | ||
|
||
|
||
|
||
#[derive(Clone,CloneRef,Debug)] | ||
pub struct Handle { | ||
pub logger : Logger, | ||
pub status_notifications : StatusNotifications, | ||
pub project : model::Project, | ||
} | ||
|
||
impl Handle { | ||
pub async fn new | ||
(project_name:ProjectName, json_endpoint:String, binary_endpoint:String) | ||
-> FallibleResult<Self> { | ||
let logger = Logger::new("controller::ide::Cloud"); | ||
// TODO[ao]: we should think how to handle engine's versions in cloud. | ||
// https://github.com/enso-org/ide/issues/1195 | ||
let version = semver::Version::parse(controller::project::ENGINE_VERSION_FOR_NEW_PROJECTS)?; | ||
let project_id = default(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't think that project_id should ever be default. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Add TODO and issue. |
||
let project = model::project::Synchronized::new_connected | ||
(&logger,None,json_endpoint,binary_endpoint,version,project_id,project_name).await?; | ||
let status_notifications = default(); | ||
Ok(Self{logger,project,status_notifications}) | ||
} | ||
} | ||
|
||
impl controller::ide::API for Handle { | ||
fn current_project(&self) -> model::Project { | ||
self.project.clone_ref() | ||
} | ||
|
||
fn status_notifications(&self) -> &StatusNotifications { &self.status_notifications } | ||
|
||
fn subscribe(&self) -> StaticBoxStream<Notification> { | ||
futures::stream::empty().boxed_local() | ||
} | ||
|
||
fn manage_projects(&self) -> Option<&dyn ManagingProjectAPI> { | ||
None | ||
} | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
use crate::prelude::*; | ||
|
||
use crate::controller::ide::API; | ||
use crate::controller::ide::ManagingProjectAPI; | ||
use crate::controller::ide::StatusNotifications; | ||
use crate::controller::ide::Notification; | ||
use crate::ide; | ||
use crate::notification; | ||
|
||
use enso_protocol::project_manager; | ||
use enso_protocol::project_manager::MissingComponentAction; | ||
use enso_protocol::project_manager::ProjectName; | ||
|
||
|
||
|
||
// ================= | ||
// === Constants === | ||
// ================= | ||
|
||
const UNNAMED_PROJECT_NAME:&str = "Unnamed"; | ||
farmaazon marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
|
||
|
||
// ============================= | ||
// === The Controller Handle === | ||
// ============================= | ||
|
||
#[derive(Clone,CloneRef,Derivative)] | ||
#[derivative(Debug)] | ||
pub struct Handle { | ||
logger : Logger, | ||
current_project : Rc<CloneRefCell<model::Project>>, | ||
#[derivative(Debug="ignore")] | ||
project_manager : Rc<dyn project_manager::API>, | ||
status_notifications : StatusNotifications, | ||
notifications : notification::Publisher<Notification>, | ||
} | ||
|
||
impl Handle { | ||
pub fn new_with_project(project_manager:Rc<dyn project_manager::API>, initial_project:model::Project) -> Self { | ||
let logger = Logger::new("controller::ide::Desktop"); | ||
let current_project = Rc::new(CloneRefCell::new(initial_project)); | ||
let status_notifications = default(); | ||
let notifications = default(); | ||
Self {logger,current_project,project_manager,status_notifications,notifications} | ||
} | ||
|
||
pub async fn new_with_opened_project(project_manager:Rc<dyn project_manager::API>, name:ProjectName) -> FallibleResult<Self> { | ||
let initializer = ide::initializer::WithProjectManager::new(Logger::new("Handle::new"),project_manager.clone_ref(),name); | ||
let model = initializer.initialize_project_model().await?; | ||
Ok(Self::new_with_project(project_manager,model)) | ||
} | ||
} | ||
|
||
impl API for Handle { | ||
fn current_project (&self) -> model::Project { self.current_project.get() } | ||
fn status_notifications(&self) -> &StatusNotifications { &self.status_notifications } | ||
|
||
fn subscribe(&self) -> StaticBoxStream<Notification> { | ||
self.notifications.subscribe().boxed_local() | ||
} | ||
|
||
fn manage_projects (&self) -> Option<&dyn ManagingProjectAPI> { | ||
Some(self) | ||
} | ||
} | ||
|
||
impl ManagingProjectAPI for Handle { | ||
fn create_new_project<'a>(&'a self) -> BoxFuture<'a, FallibleResult> { | ||
async move { | ||
|
||
let list = self.project_manager.list_projects(&None).await?; | ||
let names:HashSet<ProjectName> = list.projects.into_iter().map(|p| p.name).collect(); | ||
let candidates_with_suffix = (1..).map(|i| format!("{}_{}", UNNAMED_PROJECT_NAME, i)); | ||
let candidates = std::iter::once(UNNAMED_PROJECT_NAME.to_owned()).chain(candidates_with_suffix); | ||
let candidates = candidates.map(ProjectName); | ||
let name = candidates.skip_while(|c| names.contains(c)).next().unwrap(); | ||
let version = Some(controller::project::ENGINE_VERSION_FOR_NEW_PROJECTS.to_owned()); | ||
let action = MissingComponentAction::Install; | ||
|
||
let new_project = self.project_manager.create_project(name.deref(),&version,&action).await?.project_id; | ||
self.current_project.set(model::project::Synchronized::new_opened(&self.logger,self.project_manager.clone_ref(),new_project,name).await?); | ||
executor::global::spawn(self.notifications.publish(Notification::NewProjectCreated)); | ||
Ok(()) | ||
}.boxed_local() | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't like the name
Process
here, initially I thought about different kind of process.Perhaps something more along lines of "Job", "Task", "BackgroundAction", etc?