Compare commits
2 Commits
90b821f95c
...
6731fcd7f2
Author | SHA1 | Date |
---|---|---|
SeanOMik | 6731fcd7f2 | |
SeanOMik | 4a7cdfab80 |
|
@ -1,10 +1,12 @@
|
|||
--local cube: resource = world:request_res("loader", "assets/cube-texture-embedded.gltf")
|
||||
|
||||
--cube = nil
|
||||
|
||||
function on_init()
|
||||
local cube = world:request_res("assets/cube-texture-embedded.gltf")
|
||||
print("Loaded textured cube")
|
||||
|
||||
local pos = Transform.from_translation(Vec3.new(0, 0, -8.0))
|
||||
local cube_comp = ModelComponent.new(cube)
|
||||
|
||||
local e = world:spawn(pos, cube_comp)
|
||||
print("spawned entity " .. tostring(e))
|
||||
end
|
||||
|
||||
--[[ function on_first()
|
||||
|
|
|
@ -80,12 +80,13 @@ macro_rules! impl_fn_system_tuple {
|
|||
|
||||
fn execute_deferred(&mut self, world: NonNull<World>) -> anyhow::Result<()> {
|
||||
let state = self.arg_state.as_mut().expect("Somehow there was no state");
|
||||
state.reverse();
|
||||
|
||||
$(
|
||||
let arg_state_box = state.pop()
|
||||
.expect("Missing expected arg state");
|
||||
let arg_state = *arg_state_box.downcast::<$name::State>()
|
||||
.unwrap();
|
||||
.expect("Somehow the state cannot be downcasted from boxed Any");
|
||||
$name::apply_deferred(arg_state, world);
|
||||
)+
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@ use std::{collections::{HashMap, VecDeque, HashSet}, ptr::NonNull};
|
|||
|
||||
use super::System;
|
||||
|
||||
use crate::world::World;
|
||||
use crate::{world::World, CommandQueue, Commands};
|
||||
|
||||
#[derive(thiserror::Error, Debug)]
|
||||
pub enum GraphExecutorError {
|
||||
|
@ -58,7 +58,7 @@ impl GraphExecutor {
|
|||
}
|
||||
|
||||
/// Executes the systems in the graph
|
||||
pub fn execute(&mut self, world_ptr: NonNull<World>, stop_on_error: bool) -> Result<Vec<GraphExecutorError>, GraphExecutorError> {
|
||||
pub fn execute(&mut self, mut world_ptr: NonNull<World>, stop_on_error: bool) -> Result<Vec<GraphExecutorError>, GraphExecutorError> {
|
||||
let mut stack = VecDeque::new();
|
||||
let mut visited = HashSet::new();
|
||||
|
||||
|
@ -91,6 +91,25 @@ impl GraphExecutor {
|
|||
possible_errors.push(e);
|
||||
unimplemented!("Cannot resume topological execution from error"); // TODO: resume topological execution from error
|
||||
}
|
||||
|
||||
let world = unsafe { world_ptr.as_mut() };
|
||||
if let Some(mut queue) = world.try_get_resource_mut::<CommandQueue>() {
|
||||
// Safety: Commands only borrows world.entities when adding commands
|
||||
let world = unsafe { world_ptr.as_mut() };
|
||||
let mut commands = Commands::new(&mut queue, world);
|
||||
|
||||
let world = unsafe { world_ptr.as_mut() };
|
||||
if let Err(e) = commands.execute(world)
|
||||
.map_err(|e| GraphExecutorError::Command(e)) {
|
||||
|
||||
if stop_on_error {
|
||||
return Err(e);
|
||||
}
|
||||
|
||||
possible_errors.push(e);
|
||||
unimplemented!("Cannot resume topological execution from error"); // TODO: resume topological execution from error
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(possible_errors)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use lyra_ecs::Commands;
|
||||
use lyra_ecs::CommandQueue;
|
||||
use lyra_resource::ResourceManager;
|
||||
|
||||
use crate::EventsPlugin;
|
||||
|
@ -109,10 +109,22 @@ pub struct DefaultPlugins;
|
|||
|
||||
impl Plugin for DefaultPlugins {
|
||||
fn setup(&self, game: &mut Game) {
|
||||
CommandQueuePlugin.setup(game);
|
||||
EventsPlugin.setup(game);
|
||||
InputPlugin.setup(game);
|
||||
ResourceManagerPlugin.setup(game);
|
||||
WindowPlugin::default().setup(game);
|
||||
DeltaTimePlugin.setup(game);
|
||||
}
|
||||
}
|
||||
|
||||
/// A plugin that creates a CommandQueue, and inserts it into the world as a Resource.
|
||||
/// The queue is processed at the end of every system execution in the GraphExecutor.
|
||||
#[derive(Default)]
|
||||
pub struct CommandQueuePlugin;
|
||||
|
||||
impl Plugin for CommandQueuePlugin {
|
||||
fn setup(&self, game: &mut Game) {
|
||||
game.world_mut().add_resource(CommandQueue::default());
|
||||
}
|
||||
}
|
|
@ -47,9 +47,6 @@ impl ScriptHost for LuaHost {
|
|||
provider.setup_script(script_data, ctx)?;
|
||||
}
|
||||
|
||||
let ctx = ctx.lock().expect("Failure to get Lua ScriptContext");
|
||||
try_call_lua_function(&ctx, "on_init")?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
use std::ptr::NonNull;
|
||||
|
||||
use anyhow::anyhow;
|
||||
use lyra_ecs::{query::{Entities, ResMut, View}, CommandQueue, Commands, World};
|
||||
use lyra_ecs::{query::{Entities, ResMut, View}, World};
|
||||
use lyra_game::{game::GameStages, plugin::Plugin};
|
||||
use lyra_reflect::TypeRegistry;
|
||||
use lyra_resource::ResourceManager;
|
||||
|
@ -12,15 +10,13 @@ use crate::{GameScriptExt, ScriptApiProviders, ScriptContexts, ScriptData, Scrip
|
|||
use super::{providers::{LyraEcsApiProvider, LyraMathApiProvider, UtilityApiProvider}, LuaContext, LuaHost, LuaLoader, LuaScript};
|
||||
|
||||
/// A system that creates the script contexts in the world as new scripts are found
|
||||
pub fn lua_scripts_create_contexts<'a>(
|
||||
pub fn lua_scripts_create_contexts(
|
||||
world: &mut World,
|
||||
mut host: ResMut<LuaHost>,
|
||||
mut contexts: ResMut<ScriptContexts<LuaContext>>,
|
||||
mut providers: ResMut<ScriptApiProviders<LuaHost>>,
|
||||
view: View<(Entities, &ScriptList<LuaScript>)>,
|
||||
) -> anyhow::Result<()> {
|
||||
world.add_resource_default::<CommandQueue>();
|
||||
|
||||
for (en, scripts) in view.into_iter() {
|
||||
for script in scripts.iter() {
|
||||
if !contexts.has_context(script.id()) {
|
||||
|
@ -43,6 +39,24 @@ pub fn lua_scripts_create_contexts<'a>(
|
|||
host.setup_script(&script_data, &mut script_ctx, &mut providers)?;
|
||||
trace!("Finished setting up script");
|
||||
|
||||
// call on_init, handle the error
|
||||
let world_ptr = ScriptWorldPtr::from_ref(&world);
|
||||
match host.call_script(
|
||||
world_ptr,
|
||||
&script_data,
|
||||
&mut script_ctx,
|
||||
&mut providers,
|
||||
"on_init",
|
||||
) {
|
||||
Ok(()) => {}
|
||||
Err(e) => match e {
|
||||
ScriptError::MluaError(m) => {
|
||||
error!("Script '{}' ran into an error: {}", script.name(), m);
|
||||
}
|
||||
ScriptError::Other(_) => return Err(e.into()),
|
||||
},
|
||||
}
|
||||
|
||||
contexts.add_context(script.id(), script_ctx);
|
||||
break;
|
||||
} else {
|
||||
|
@ -52,14 +66,6 @@ pub fn lua_scripts_create_contexts<'a>(
|
|||
}
|
||||
}
|
||||
|
||||
let mut ptr = NonNull::from(world);
|
||||
let world = unsafe { ptr.as_ref() };
|
||||
let mut queue = world.get_resource_mut::<CommandQueue>();
|
||||
|
||||
let mut commands = Commands::new(&mut queue, unsafe { ptr.as_mut() });
|
||||
commands.execute(unsafe { ptr.as_mut() }).unwrap();
|
||||
//commands.execute(unsafe { world_ptr.as_mut() } )?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
use std::{ptr::NonNull, sync::Arc};
|
||||
|
||||
use crate::{ScriptBorrow, ScriptDynamicBundle, ScriptEntity, ScriptWorldPtr};
|
||||
use crate::{ScriptBorrow, ScriptEntity, ScriptWorldPtr};
|
||||
use elua::AsLua;
|
||||
use lyra_ecs::{query::dynamic::QueryDynamicType, Commands, DynamicBundle};
|
||||
use lyra_ecs::{query::dynamic::QueryDynamicType, CommandQueue, Commands, DynamicBundle, World};
|
||||
use lyra_reflect::{ReflectWorldExt, RegisteredType, TypeRegistry};
|
||||
use lyra_resource::ResourceManager;
|
||||
|
||||
|
@ -64,10 +64,38 @@ impl elua::Userdata for ScriptWorldPtr {
|
|||
builder: &mut elua::UserdataBuilder<'a, Self>,
|
||||
) -> elua::Result<()> {
|
||||
builder
|
||||
.method_mut("spawn", |_, this, bundle: ScriptDynamicBundle| {
|
||||
.method_mut("spawn", |_, this, vals: elua::ValueVec| {
|
||||
let world = this.as_mut();
|
||||
|
||||
Ok(ScriptEntity(world.spawn(bundle.0)))
|
||||
let mut bundle = DynamicBundle::new();
|
||||
|
||||
//while let Some(val) = vals.pop_front() {
|
||||
for (i, val) in vals.into_iter().enumerate() {
|
||||
let ud = val.as_userdata().ok_or(
|
||||
elua::Error::bad_arg(
|
||||
Some("World:spawn"),
|
||||
2 + i as i32, // i starts at 0
|
||||
Some("components..."),
|
||||
Arc::new(elua::Error::runtime("provided component is not userdata")),
|
||||
))?;
|
||||
|
||||
let script_brw = ud.execute_method::<_, ScriptBorrow>(FN_NAME_INTERNAL_REFLECT, ())?;
|
||||
let reflect = script_brw.reflect_branch.as_component_unchecked();
|
||||
|
||||
let refl_data = script_brw.data.unwrap();
|
||||
//let refl_data = refl_data.as_ref();
|
||||
reflect.bundle_insert(&mut bundle, refl_data);
|
||||
}
|
||||
|
||||
// defer the entity spawn
|
||||
// safety: Commands borrows Entities from World, the resource borrows from the world resouces,
|
||||
// they are borrowing different parts of World.
|
||||
let world_ptr: *mut World = world;
|
||||
let mut commands_queue = world.get_resource_mut::<CommandQueue>();
|
||||
let mut commands = Commands::new(&mut commands_queue, unsafe { &mut *world_ptr });
|
||||
let entity = commands.spawn(bundle);
|
||||
|
||||
Ok(ScriptEntity(entity))
|
||||
})
|
||||
.method_mut(
|
||||
"view",
|
||||
|
|
Loading…
Reference in New Issue