Skip to content

Instantly share code, notes, and snippets.

@leo60228
Created April 24, 2023 01:17
Show Gist options
  • Save leo60228/c770507aaa66ae50e439641209d3e3ff to your computer and use it in GitHub Desktop.
Save leo60228/c770507aaa66ae50e439641209d3e3ff to your computer and use it in GitHub Desktop.
#[cxx_qt::bridge]
mod instances_model {
use helixlauncher_core::config::Config;
use helixlauncher_core::game::{merge_components, prepare_launch, LaunchOptions};
use helixlauncher_core::instance::{Instance, InstanceLaunch, Modloader};
use helixlauncher_core::launcher::launch;
use tokio::runtime::Runtime;
unsafe extern "C++" {
include!(< QAbstractListModel >);
include!("cxx-qt-lib/qstring.h");
type QString = cxx_qt_lib::QString;
include!("cxx-qt-lib/qhash.h");
type QHash_i32_QByteArray = cxx_qt_lib::QHash<cxx_qt_lib::QHashPair_i32_QByteArray>;
include!("cxx-qt-lib/qvariant.h");
type QVariant = cxx_qt_lib::QVariant;
include!("cxx-qt-lib/qmodelindex.h");
type QModelIndex = cxx_qt_lib::QModelIndex;
}
#[cxx_qt::qobject(
base = "QAbstractListModel",
qml_uri = "dev.helixlauncher.qml",
qml_version = "1.0",
qml_singleton
)]
#[derive(Default)]
pub struct InstancesModel;
#[cxx_qt::inherit]
extern "C++" {
unsafe fn begin_reset_model(self: Pin<&mut qobject::InstancesModel>);
unsafe fn end_reset_model(self: Pin<&mut qobject::InstancesModel>);
}
impl qobject::InstancesModel {
#[qinvokable(cxx_override)]
fn row_count(&self, _parent: &QModelIndex) -> i32 {
let config = Config::new("dev.helixlauncher.HelixLauncher", "HelixLauncher").unwrap();
let instances = Instance::list_instances(config.get_instances_path()).unwrap();
instances.len() as _
}
#[qinvokable(cxx_override)]
fn data(&self, index: &QModelIndex, role: i32) -> QVariant {
let config = Config::new("dev.helixlauncher.HelixLauncher", "HelixLauncher").unwrap();
let mut instances = Instance::list_instances(config.get_instances_path()).unwrap();
instances.sort_by(|x, y| x.path.cmp(&y.path));
if let Some(elem) = instances.get(index.row() as usize) {
if role == 0x100 {
QVariant::from(&QString::from(&elem.config.name[..]))
} else if role == 0x101 {
for component in &elem.config.components {
if component.id == "net.fabricmc.fabric-loader" {
return QVariant::from(&QString::from("Fabric"));
} else if component.id == "org.quiltmc.quilt-loader" {
return QVariant::from(&QString::from("Quilt"));
} else if component.id == "net.minecraftforge.forge" {
return QVariant::from(&QString::from("Forge"));
}
}
QVariant::default()
} else if role == 0x102 {
let minecraft = elem
.config
.components
.iter()
.find(|x| x.id == "net.minecraft");
if let Some(minecraft) = minecraft {
QVariant::from(&QString::from(&minecraft.version[..]))
} else {
QVariant::default()
}
} else {
QVariant::default()
}
} else {
QVariant::default()
}
}
#[qinvokable(cxx_override)]
fn role_names(&self) -> QHash_i32_QByteArray {
let mut map = QHash_i32_QByteArray::default();
map.insert(0x100, "name".into());
map.insert(0x101, "loader".into());
map.insert(0x102, "version".into());
map
}
#[qinvokable]
fn launch(&self, item: i32) {
std::thread::spawn(move || {
let config =
Config::new("dev.helixlauncher.HelixLauncher", "HelixLauncher").unwrap();
let mut instances = Instance::list_instances(config.get_instances_path()).unwrap();
instances.sort_by(|x, y| x.path.cmp(&y.path));
let instance = &instances[item as usize];
let rt = Runtime::new().unwrap();
rt.block_on(async move {
let components = merge_components(&config, &instance.config.components)
.await
.unwrap();
let prepared =
prepare_launch(&config, instance, &components, LaunchOptions::default())
.await
.unwrap();
launch(&prepared, true).await.unwrap();
});
});
}
#[qinvokable]
fn create_instance(
mut self: Pin<&mut Self>,
name: QString,
version: QString,
modloader_string: QString,
modloader_version: QString,
) {
let config = Config::new("dev.helixlauncher.HelixLauncher", "HelixLauncher").unwrap();
let modloader = match &*modloader_string.to_string() {
"Quilt" => Modloader::Quilt,
"Fabric" => Modloader::Fabric,
"Forge" => Modloader::Forge,
"" => Modloader::Vanilla,
_ => unreachable!(),
};
Instance::new(
name.to_string(),
version.to_string(),
InstanceLaunch::default(),
&config.get_instances_path(),
modloader,
Some(modloader_version.to_string()),
)
.unwrap();
unsafe {
self.as_mut().begin_reset_model();
self.as_mut().end_reset_model();
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment