/* ----------------------------------------------------------------------------- GSFramework Copyright 2001-2013 Emmanuel Julien. All Rights Reserved. ----------------------------------------------------------------------------- */ #include "script_squirrel/engine_vm.h" #include "script_squirrel/cobject/cobject.h" #include "script_squirrel/cobject/cobject_decl.h" #include "script_squirrel/legacy/squirrel_binding.h" #include "script/scripted_object.h" #include "script/script_variant.h" #include "log/log.h" using namespace GS::Script; //------------------------------------------------------------------------------ bool EngineVM::Open() { if (!SquirrelVM::Open()) return false; #define __SQ_REGISTERINT(__NAME__, __V__) sq_pushstring(vm, __NAME__, -1); sq_pushinteger(vm, __V__); sq_newslot(vm, -3, true); sq_pushroottable(vm); __SQ_REGISTERINT("objectTypeUndefined", typetag_Undefined) __SQ_REGISTERINT("objectTypeDeleted", typetag_Deleted) __SQ_REGISTERINT("objectTypeEngine", typetag_Engine) __SQ_REGISTERINT("objectTypeResourceCache", typetag_ResourceSet) __SQ_REGISTERINT("objectTypeProject", typetag_Project) __SQ_REGISTERINT("objectTypeRenderer", typetag_Renderer) __SQ_REGISTERINT("objectTypeRaytracer", typetag_Raytracer) __SQ_REGISTERINT("objectTypeMixer", typetag_Mixer) __SQ_REGISTERINT("objectTypeScene", typetag_Scene3d) __SQ_REGISTERINT("objectTypeClock", typetag_Clock) __SQ_REGISTERINT("objectTypeFont", typetag_Font) __SQ_REGISTERINT("objectTypeRasterFont", typetag_RasterFont) __SQ_REGISTERINT("objectTypeUI", typetag_Scene2d) __SQ_REGISTERINT("objectTypeUICursor", typetag_UICursor) __SQ_REGISTERINT("objectTypeWindow", typetag_Window) __SQ_REGISTERINT("objectTypeWidget", typetag_Widget) __SQ_REGISTERINT("objectTypeSizerWidget", typetag_SizerWidget) __SQ_REGISTERINT("objectTypeContainerWidget", typetag_ContainerWidget) __SQ_REGISTERINT("objectTypeSpacerWidget", typetag_SpacerWidget) __SQ_REGISTERINT("objectTypeCanvasWidget", typetag_CanvasWidget) __SQ_REGISTERINT("objectTypeTextWidget", typetag_TextWidget) __SQ_REGISTERINT("objectTypeBitmapWidget", typetag_BitmapWidget) __SQ_REGISTERINT("objectTypeCheckWidget", typetag_CheckWidget) __SQ_REGISTERINT("objectTypePicture", typetag_Picture) __SQ_REGISTERINT("objectTypeGroup", typetag_Group) __SQ_REGISTERINT("objectTypeItem", typetag_Item) __SQ_REGISTERINT("objectTypeCamera", typetag_Camera) __SQ_REGISTERINT("objectTypeObject", typetag_Object) __SQ_REGISTERINT("objectTypeLight", typetag_Light) __SQ_REGISTERINT("objectTypeInstance", typetag_Instance) __SQ_REGISTERINT("objectTypeMotion", typetag_Motion) __SQ_REGISTERINT("objectTypeTrigger", typetag_Trigger) __SQ_REGISTERINT("objectTypePath", typetag_Path) __SQ_REGISTERINT("objectTypeSound", typetag_Sound) __SQ_REGISTERINT("objectTypeTexture", typetag_Texture) __SQ_REGISTERINT("objectTypeGeometry", typetag_Geometry) __SQ_REGISTERINT("objectTypeMaterial", typetag_Material) __SQ_REGISTERINT("objectTypeColShape", typetag_ColShape) __SQ_REGISTERINT("objectTypeConstraint", typetag_Constraint) __SQ_REGISTERINT("objectTypeMetafile", typetag_Metafile) __SQ_REGISTERINT("objectTypeMetatag", typetag_Metatag) __SQ_REGISTERINT("objectTypeHidDevice", typetag_InputDevice) __SQ_REGISTERINT("objectTypeEditorPlugin", typetag_EditorPlugin) __SQ_REGISTERINT("objectTypeProjectScene", typetag_ProjectScene) __SQ_REGISTERINT("objectTypeProjectLayer", typetag_ProjectLayer) __SQ_REGISTERINT("objectTypeAnimationSource", typetag_AutomationSource) __SQ_REGISTERINT("objectTypeAnimationSourceGroup", typetag_AutomationSourceGroup) sq_pop(vm, 1); _INIT_CLASS(vm, CObject); RegisterAllSquirrelBinding(vm); return true; } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ bool EngineVM::PushVariant(const Variant &v) { if (v.type == Variant::Type_UserObject) return CObject::Push(vm, v.ptr, (CObjectType)v.typetag); return SquirrelVM::PushVariant(v); } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ int EngineVM::InvalidateNativeReference(void *ptr) { uint invalidated_count = 0; ListForeachPtr(CObject *, o, cobjects) if (o->native == ptr) { cobjects.Remove(o); o->list_item = NULL; o->type = typetag_Deleted; o->native = NULL; ++invalidated_count; } // __LOG_E__ << "Invalidate native object " << nString::Format("0x%x", ptr) << " - reference found: " << count << ", CObject left: " << safe_ptr_list.GetCount() << ".\n"; return invalidated_count; } void EngineVM::ReleaseAllNativeReferences() { ListForeachPtr(CObject *, o, cobjects) o->Release(); } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ void EngineVM::Close() { /* [EJ] We have to drop all native object references now. If we don't, native objects holding a reference to a script object will crash the VM when they try to release it from their destructor (hence making a reentrant call into the VM). */ ReleaseAllNativeReferences(); SquirrelVM::Close(); } //------------------------------------------------------------------------------