use crate::callback::init_context_with_callback;
use crate::callback::G_VARS;
use crate::common::*;
use crate::common::{collect_js_files, collect_module_dirs, str_2_v8};
use crate::session_cache::CallbackSharedData;
use rusty_v8 as v8;
use rusty_v8::{Context, HandleScope, Isolate, Local};
use std::collections::HashMap;
use std::fs;
use std::fs::File;
use std::io::{BufRead, BufReader};
use std::path::Path;
use v_module::module::Module;
pub fn script_origin<'a>(s: &mut v8::HandleScope<'a>, resource_name: v8::Local<'a, v8::String>) -> v8::ScriptOrigin<'a> {
let resource_line_offset = 0;
let resource_column_offset = 0;
let resource_is_shared_cross_origin = false;
let script_id = 123;
let source_map_url = v8::String::new(s, "").unwrap();
let resource_is_opaque = true;
let is_wasm = false;
let is_module = false;
v8::ScriptOrigin::new(
s,
resource_name.into(),
resource_line_offset,
resource_column_offset,
resource_is_shared_cross_origin,
script_id,
source_map_url.into(),
resource_is_opaque,
is_wasm,
is_module,
)
}
impl<'a, T: Default> ScriptInfo<'a, T> {
pub fn new_with_src(id: &str, src: &str) -> Self {
Self {
id: id.to_string(),
str_script: src.to_string(),
compiled_script: None,
dependency: Default::default(),
context: Default::default(),
}
}
pub fn compile_script(&mut self, js_name: &str, parent_scope: &mut HandleScope<'a>) {
let source = str_2_v8(parent_scope, &self.str_script);
let name = v8::String::new(parent_scope, js_name).unwrap();
let origin = script_origin(parent_scope, name);
match v8::Script::compile(parent_scope, source, Some(&origin)) {
Some(script) => {
self.compiled_script = Some(script);
}
None => {
error!("fail compile script {}", self.str_script);
self.compiled_script = None;
}
}
}
}
pub struct ScriptsWorkPlace<'a, T> {
pub scripts: HashMap<String, ScriptInfo<'a, T>>,
pub scripts_order: Vec<String>,
pub module: Module,
pub scope: HandleScope<'a, ()>,
pub context: Local<'a, Context>,
}
impl<'a, T: Default> ScriptsWorkPlace<'a, T> {
pub fn load_ext_scripts(&mut self, sys_ticket: &str) {
let mut modules_de = vec![];
let mut o_files = vec![];
collect_module_dirs("./public/modules", &mut modules_de);
let scripts_location = if let Some(s) = Module::get_property("scripts_location") {
vec![s]
} else {
vec!["./public/js/common".to_owned(), "./public/js/server".to_owned()]
};
for p in scripts_location.iter() {
let path = p.to_owned() + "/";
let seq = path.to_string() + ".seq";
if Path::new(&seq).exists() {
match File::open(&seq) {
Ok(f) => {
let file = BufReader::new(&f);
for line in file.lines() {
match line {
Ok(file_name) => {
if file_name == "$modules" {
for x in modules_de.iter() {
o_files.push(x.to_owned());
}
} else {
collect_js_files(&(path.to_string() + &file_name), &mut o_files);
}
}
Err(e) => error!("{:?}", e),
}
}
}
Err(e) => error!("{:?}", e),
}
} else {
collect_js_files(&path, &mut o_files);
}
}
let mut session_data = CallbackSharedData::default();
session_data.g_key2attr.insert("$ticket".to_owned(), sys_ticket.to_owned());
let mut sh_g_vars = G_VARS.lock().unwrap();
let g_vars = sh_g_vars.get_mut();
*g_vars = session_data;
drop(sh_g_vars);
for x in o_files.iter() {
match fs::read_to_string(x) {
Ok(f) => {
info!("{}", x);
let mut scr_inf: ScriptInfo<T> = ScriptInfo::new_with_src(x, &f);
let scope = &mut v8::ContextScope::new(&mut self.scope, self.context);
scr_inf.compile_script(x, scope);
if let Some(i_script) = scr_inf.compiled_script {
i_script.run(scope);
}
}
Err(e) => error!("{:?}", e),
}
}
}
pub fn new(isolate: &'a mut Isolate) -> Self {
let mut scope = v8::HandleScope::new(isolate);
let context = init_context_with_callback(&mut scope);
Self {
scripts: Default::default(),
scripts_order: vec![],
module: Module::default(),
scope,
context,
}
}
pub fn add_to_order(&mut self, scr_inf: &ScriptInfo<T>) {
let mut count_find_dependency = 0;
let mut inserted = false;
let mut new_scripts_order = vec![];
for oo in self.scripts_order.iter() {
if count_find_dependency < scr_inf.dependency.vec.len() {
if let Some(soo) = self.scripts.get(oo) {
for dp in soo.dependency.vec.iter() {
if scr_inf.id == *dp {
count_find_dependency += 1;
}
}
}
}
if !inserted && count_find_dependency >= scr_inf.dependency.vec.len() {
new_scripts_order.push(scr_inf.id.to_owned());
inserted = true;
}
if *oo != scr_inf.id {
new_scripts_order.push(oo.to_owned());
}
}
if !inserted {
new_scripts_order.push(scr_inf.id.to_owned());
}
self.scripts_order = new_scripts_order;
}
}