From ae1f5a3c8956cfae3bfb76e37494470955faf12e Mon Sep 17 00:00:00 2001 From: Lukas Joergensen Date: Sat, 21 Apr 2018 10:11:01 +0200 Subject: [PATCH 1/3] Update the CInterface --- .../source/cinterface/c_consoleInterface.cpp | 143 +---- .../source/cinterface/c_controlInterface.cpp | 239 +++++++++ Engine/source/cinterface/c_controlInterface.h | 48 ++ Engine/source/cinterface/c_scripting.cpp | 426 --------------- Engine/source/cinterface/c_simInterface.cpp | 54 ++ .../cinterface/c_simdatablockInterface.cpp | 40 ++ .../cinterface/c_simobjectInterface.cpp | 71 +++ Engine/source/cinterface/cinterface.cpp | 499 +++--------------- Engine/source/cinterface/cinterface.h | 39 +- Engine/source/platformMac/macFileIO.mm | 2 +- 10 files changed, 576 insertions(+), 985 deletions(-) create mode 100644 Engine/source/cinterface/c_controlInterface.cpp create mode 100644 Engine/source/cinterface/c_controlInterface.h delete mode 100644 Engine/source/cinterface/c_scripting.cpp create mode 100644 Engine/source/cinterface/c_simInterface.cpp create mode 100644 Engine/source/cinterface/c_simdatablockInterface.cpp create mode 100644 Engine/source/cinterface/c_simobjectInterface.cpp diff --git a/Engine/source/cinterface/c_consoleInterface.cpp b/Engine/source/cinterface/c_consoleInterface.cpp index 21a2e48fd..09b406da3 100644 --- a/Engine/source/cinterface/c_consoleInterface.cpp +++ b/Engine/source/cinterface/c_consoleInterface.cpp @@ -20,154 +20,59 @@ // IN THE SOFTWARE. //----------------------------------------------------------------------------- -#include "platform/platform.h" -#include "console/compiler.h" #include "console/consoleInternal.h" #include "console/simSet.h" +#include "console/engineAPI.h" -extern "C" { - - // SimObject C interface - const char *SimObject_GetName(SimObject *so) +namespace Con +{ + DefineNewEngineFunction(AddConsumer, void, (ConsumerCallback cb), , "") { - return so->getName(); + addConsumer(cb); } - U32 SimObject_GetId(SimObject *so) + DefineNewEngineFunction(RemoveConsumer, void, (ConsumerCallback cb), , "") { - return so->getId(); + removeConsumer(cb); } - const char *SimObject_GetClassName(SimObject *so) + DefineNewEngineFunction(GetConsoleString, String, (String name),, "") { - return so->getClassName(); + return getVariable(StringTable->insert(name)); } - void *SimObject_GetFieldList(SimObject *so, S32 &outNumFields) + DefineNewEngineFunction(SetConsoleString, void, (String name, String value),, "") { - const AbstractClassRep::FieldList &fl = so->getFieldList(); - outNumFields = fl.size(); - return fl.address(); + setVariable(StringTable->insert(name), StringTable->insert(value)); } - bool SimObject_IsLocked(SimObject *so) + DefineNewEngineFunction(GetConsoleInt, S32, (String name),, "") { - return so->isLocked(); + return getIntVariable(StringTable->insert(name)); } - void SimObject_SetDataField(SimObject *so, const char *fieldName, const char *arr, const char *val) + DefineNewEngineFunction(SetConsoleInt, void, (String name, S32 value),, "") { - so->setDataField(StringTable->insert(fieldName), arr, val); + setIntVariable(StringTable->insert(name), value); } - const char *SimObject_GetDataField(SimObject *so, const char *fieldName, const char *arr) + DefineNewEngineFunction(GetConsoleFloat, F32, (String name),, "") { - return so->getDataField(StringTable->insert(fieldName), arr); + return getFloatVariable(StringTable->insert(name)); } - void SimObject_InspectPreApply(SimObject *so) + DefineNewEngineFunction(SetConsoleFloat, void, (String name, F32 value),, "") { - so->inspectPreApply(); + setFloatVariable(StringTable->insert(name), value); } - void SimObject_InspectPostApply(SimObject *so) + DefineNewEngineFunction(GetConsoleBool, bool, (String name),, "") { - so->inspectPostApply(); + return getBoolVariable(StringTable->insert(name)); } - // Con C interface - void Con_AddConsumer(ConsumerCallback cb) + DefineNewEngineFunction(SetConsoleBool, void, (String name, bool value),, "") { - Con::addConsumer(cb); + setBoolVariable(StringTable->insert(name), value); } - - void Con_RemoveConsumer(ConsumerCallback cb) - { - Con::removeConsumer(cb); - } - - void Con_AddCommand_String(StringCallback cb, const char *nameSpace, const char *funcName, const char* usage, S32 minArgs, S32 maxArgs) - { - if (!nameSpace || !dStrlen(nameSpace)) - Con::addCommand(funcName, cb, usage, minArgs + 1, maxArgs + 1); - else - Con::addCommand(nameSpace, funcName, cb, usage, minArgs + 1, maxArgs + 1); - } - - // ConsoleBaseType C interface - ConsoleBaseType *ConsoleBaseType_GetTypeById(const S32 typeId) - { - return ConsoleBaseType::getType(typeId); - } - - S32 ConsoleBaseType_GetTypeId(ConsoleBaseType *cbt) - { - return cbt->getTypeID(); - } - - S32 ConsoleBaseType_GetTypeSize(ConsoleBaseType *cbt) - { - return cbt->getTypeSize(); - } - - const char *ConsoleBaseType_GetTypeName(ConsoleBaseType *cbt) - { - return cbt->getTypeName(); - } - - const char *ConsoleBaseType_GetInspectorFieldType(ConsoleBaseType *cbt) - { - return cbt->getInspectorFieldType(); - } - - void ConsoleBaseType_SetData(ConsoleBaseType *cbt, void *dptr, S32 argc, const char **argv, const EnumTable *tbl, BitSet32 flag) - { - return cbt->setData(dptr, argc, argv, tbl, flag); - } - - const char *ConsoleBaseType_GetData(ConsoleBaseType *cbt, void *dptr, const EnumTable *tbl, BitSet32 flag) - { - return cbt->getData(dptr, tbl, flag); - } - - // Abstract Class Rep - AbstractClassRep *AbstractClassRep_GetCommonParent(AbstractClassRep *acr, AbstractClassRep *otheracr) - { - return acr->getCommonParent(otheracr); - } - - AbstractClassRep *AbstractClassRep_FindClassRep(const char* in_pClassName) - { - return AbstractClassRep::findClassRep(in_pClassName); - } - - U32 AbstractClassRep_GetFieldStructSize() - { - return sizeof(AbstractClassRep::Field); - } - - // Sim C interface - SimObject *Sim_FindObjectByString(const char *param) - { - return Sim::findObject(param); - } - - SimObject *Sim_FindObjectById(S32 param) - { - return Sim::findObject(param); - } - - // Sim Set - SimObject **SimSet_Begin(SimObject *simObject) - { - return dynamic_cast(simObject)->begin(); - } - - SimObject **SimSet_End(SimObject *simObject) - { - return dynamic_cast(simObject)->end(); - } - -}; - - +} \ No newline at end of file diff --git a/Engine/source/cinterface/c_controlInterface.cpp b/Engine/source/cinterface/c_controlInterface.cpp new file mode 100644 index 000000000..4a07d49db --- /dev/null +++ b/Engine/source/cinterface/c_controlInterface.cpp @@ -0,0 +1,239 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#include "c_controlInterface.h" + +#include "console/consoleInternal.h" +#include "console/simSet.h" +#include "app/mainLoop.h" +#include "windowManager/platformWindow.h" +#include "windowManager/platformWindowMgr.h" + +#ifdef TORQUE_OS_WIN +#include "windowManager/win32/win32Window.h" +#include "windowManager/win32/winDispatch.h" +extern void createFontInit(void); +extern void createFontShutdown(void); +#endif + + +#if defined( TORQUE_MINIDUMP ) && defined( TORQUE_RELEASE ) +extern S32 CreateMiniDump(LPEXCEPTION_POINTERS ExceptionInfo); +#endif + +extern bool LinkConsoleFunctions; + +extern "C" { + + // reset the engine, unloading any current level and returning to the main menu + void torque_reset() + { + Con::evaluate("disconnect();"); + } + + // initialize Torque 3D including argument handling + bool torque_engineinit(S32 argc, const char **argv) + { + +#if defined( TORQUE_MINIDUMP ) && defined( TORQUE_RELEASE ) + __try { +#endif + + LinkConsoleFunctions = true; + +#if defined(_MSC_VER) + createFontInit(); +#endif + + // Initialize the subsystems. + StandardMainLoop::init(); + + // Handle any command line args. + if (!StandardMainLoop::handleCommandLine(argc, argv)) + { + Platform::AlertOK("Error", "Failed to initialize game, shutting down."); + return false; + } + +#if defined( TORQUE_MINIDUMP ) && defined( TORQUE_RELEASE ) + } + + __except (CreateMiniDump(GetExceptionInformation())) + { + _exit(0); + } +#endif + + return true; + + } + + // tick Torque 3D's main loop + S32 torque_enginetick() + { + +#if defined( TORQUE_MINIDUMP ) && defined( TORQUE_RELEASE ) + __try { +#endif + + bool ret = StandardMainLoop::doMainLoop(); + return ret; + +#if defined( TORQUE_MINIDUMP ) && defined( TORQUE_RELEASE ) + } + __except (CreateMiniDump(GetExceptionInformation())) + { + _exit(0); + } +#endif + + } + + S32 torque_getreturnstatus() + { + return StandardMainLoop::getReturnStatus(); + } + + // signal an engine shutdown (as with the quit(); console command) + void torque_enginesignalshutdown() + { + Con::evaluate("quit();"); + } + + // shutdown the engine + S32 torque_engineshutdown() + { + +#if defined( TORQUE_MINIDUMP ) && defined( TORQUE_RELEASE ) + __try { +#endif + + // Clean everything up. + StandardMainLoop::shutdown(); + +#if defined(_MSC_VER) + createFontShutdown(); +#endif + +#if defined( TORQUE_MINIDUMP ) && defined( TORQUE_RELEASE ) + } + + __except (CreateMiniDump(GetExceptionInformation())) + { + _exit(0); + } +#endif + + // Return. + return true; + + } + + bool torque_isdebugbuild() + { +#ifdef _DEBUG + return true; +#else + return false; +#endif + + } + + // set Torque 3D into web deployment mode (disable fullscreen exlusive mode, etc) + void torque_setwebdeployment() + { + Platform::setWebDeployment(true); + } + + // resize the Torque 3D child window to the specified width and height + void torque_resizewindow(S32 width, S32 height) + { + if (PlatformWindowManager::get() && PlatformWindowManager::get()->getFirstWindow()) + PlatformWindowManager::get()->getFirstWindow()->setSize(Point2I(width, height)); + } + +#if defined(TORQUE_OS_WIN) && !defined(TORQUE_SDL) + // retrieve the hwnd of our render window + void* torque_gethwnd() + { + if (PlatformWindowManager::get() && PlatformWindowManager::get()->getFirstWindow()) + { + Win32Window* w = (Win32Window*)PlatformWindowManager::get()->getFirstWindow(); + return (void *)w->getHWND(); + } + + return NULL; + } + + // directly add a message to the Torque 3D event queue, bypassing the Windows event queue + // this is useful in the case of the IE plugin, where we are hooking into an application + // level message, and posting to the windows queue would cause a hang + void torque_directmessage(U32 message, U32 wparam, U32 lparam) + { + if (PlatformWindowManager::get() && PlatformWindowManager::get()->getFirstWindow()) + { + Win32Window* w = (Win32Window*)PlatformWindowManager::get()->getFirstWindow(); + Dispatch(DelayedDispatch, w->getHWND(), message, wparam, lparam); + } + } + +#endif + +#ifdef TORQUE_OS_WIN + void torque_inputevent(S32 type, S32 value1, S32 value2) + { + if (PlatformWindowManager::get() && PlatformWindowManager::get()->getFirstWindow()) + { + Win32Window* w = (Win32Window*)PlatformWindowManager::get()->getFirstWindow(); + WindowId devId = w->getWindowId(); + + switch (type) + { + case 0: + w->mouseEvent.trigger(devId, 0, value1, value2, w->isMouseLocked()); + break; + case 1: + if (value2) + w->buttonEvent.trigger(devId, 0, IA_MAKE, value1); + else + w->buttonEvent.trigger(devId, 0, IA_BREAK, value1); + break; + + } + } + } +#endif + + static char* gExecutablePath = NULL; + + const char* torque_getexecutablepath() + { + return gExecutablePath; + } + + void torque_setexecutablepath(const char* directory) + { + dsize_t pathLen = dStrlen(directory) + 1; + gExecutablePath = new char[pathLen]; + dStrcpy(gExecutablePath, directory, pathLen); + } +} \ No newline at end of file diff --git a/Engine/source/cinterface/c_controlInterface.h b/Engine/source/cinterface/c_controlInterface.h new file mode 100644 index 000000000..229b07b88 --- /dev/null +++ b/Engine/source/cinterface/c_controlInterface.h @@ -0,0 +1,48 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#ifndef C_CONTROLINTERFACE_H +#define C_CONTROLINTERFACE_H +#include "platform/platformDlibrary.h" +#include "console/engineFunctions.h" + +TORQUE_API void torque_reset(); +TORQUE_API bool torque_engineinit(S32 argc, const char **argv); +TORQUE_API S32 torque_enginetick(); +TORQUE_API S32 torque_getreturnstatus(); +TORQUE_API void torque_enginesignalshutdown(); +TORQUE_API S32 torque_engineshutdown(); +TORQUE_API bool torque_isdebugbuild(); +TORQUE_API void torque_setwebdeployment(); +TORQUE_API void torque_resizewindow(S32 width, S32 height); + +#if defined(TORQUE_OS_WIN) && !defined(TORQUE_SDL) +TORQUE_API void* torque_gethwnd(); +TORQUE_API void torque_directmessage(U32 message, U32 wparam, U32 lparam); +#endif +#ifdef TORQUE_OS_WIN +TORQUE_API void torque_inputevent(S32 type, S32 value1, S32 value2); +#endif + +TORQUE_API const char* torque_getexecutablepath(); + +#endif // C_CONTROLINTERFACE_H diff --git a/Engine/source/cinterface/c_scripting.cpp b/Engine/source/cinterface/c_scripting.cpp deleted file mode 100644 index f10effde2..000000000 --- a/Engine/source/cinterface/c_scripting.cpp +++ /dev/null @@ -1,426 +0,0 @@ -//----------------------------------------------------------------------------- -// Copyright (c) 2012 GarageGames, LLC -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to -// deal in the Software without restriction, including without limitation the -// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -// sell copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS -// IN THE SOFTWARE. -//----------------------------------------------------------------------------- - -#include "platform/platform.h" -#include "console/compiler.h" -#include "console/console.h" -#include "console/consoleInternal.h" -#include "core/util/tDictionary.h" -#include "app/mainLoop.h" - -// External scripting cinterface, suitable for import into any scripting system which support "C" interfaces (C#, Python, Lua, Java, etc) - -#ifdef TORQUE_OS_WIN -#include "windowManager/win32/win32Window.h" -#include "windowManager/win32/winDispatch.h" -#endif - -extern "C" { - - struct MarshalNativeEntry - { - const char* nameSpace; - const char* name; - Namespace::Entry* entry; - S32 minArgs; - S32 maxArgs; - S32 cbType; - }; - - - static Namespace::Entry* GetEntry(const char* nameSpace, const char* name) - { - Namespace* ns = NULL; - - if (!nameSpace || !dStrlen(nameSpace)) - ns = Namespace::mGlobalNamespace; - else - { - nameSpace = StringTable->insert(nameSpace); - ns = Namespace::find(nameSpace); //can specify a package here, maybe need, maybe not - } - - if (!ns) - return NULL; - - name = StringTable->insert(name); - - Namespace::Entry* entry = ns->lookupRecursive(name); - - return entry; - } - - const char * script_getconsolexml() - { - Namespace::Entry* entry = GetEntry("", "consoleExportXML"); - - if (!entry) - return ""; - - static const char* exportArgv[1] = { "consoleExportXML" }; - static StringStackConsoleWrapper exportCmd(1, exportArgv); - - return entry->cb.mStringCallbackFunc(NULL, exportCmd.argc, exportCmd.argv); - } - - MarshalNativeEntry* script_get_namespace_entry(const char* nameSpace, const char* name) - { - static MarshalNativeEntry mentry; - - Namespace::Entry* e = GetEntry(nameSpace, name); - - if (!e) - return NULL; - - mentry.nameSpace = e->mNamespace->mName; - mentry.name = e->mFunctionName; - mentry.minArgs = e->mMinArgs; - mentry.maxArgs = e->mMaxArgs; - mentry.cbType = e->mType; - mentry.entry = e; - - return &mentry; - } - - void* script_get_stringtable_entry(const char* string) - { - return (void*)StringTable->insert(string); - } - - // FIELD ACCESS - - // fieldNames must be from stringTable coming in! See Engine.stringTable - - const char* script_simobject_getfield_string(U32 id, const char* fieldName) - { - SimObject *object = Sim::findObject( id ); - if( object ) - { - return (const char *) object->getDataField(fieldName, ""); - } - return ""; - } - - void script_simobject_setfield_string(U32 objectId, const char* fieldName, const char* v) - { - SimObject *object = Sim::findObject( objectId ); - if( object ) - { - object->setDataField(fieldName, "", v); - } - } - - - bool script_simobject_getfield_bool(U32 objectId, const char* fieldName) - { - SimObject *object = Sim::findObject( objectId ); - if( object ) - { - const char *v = object->getDataField(fieldName, ""); - - return dAtob(v); - } - - return false; - } - - void script_simobject_setfield_bool(U32 objectId, const char* fieldName, bool v) - { - SimObject *object = Sim::findObject( objectId ); - if( object ) - { - object->setDataField(fieldName, "", v ? "1" : "0"); - } - } - - S32 script_simobject_getfield_int(U32 objectId, const char* fieldName) - { - SimObject *object = Sim::findObject( objectId ); - if( object ) - { - const char *v = object->getDataField(fieldName, ""); - - return dAtoi(v); - } - - return false; - } - - void script_simobject_setfield_int(U32 objectId, const char* fieldName, S32 v) - { - SimObject *object = Sim::findObject( objectId ); - if( object ) - { - // this seems pretty lame, though it is how it is handled in consoleType.cpp - char buf[256]; - dSprintf(buf, 256, "%d", v ); - object->setDataField(fieldName, "", buf); - } - } - - F32 script_simobject_getfield_float(U32 objectId, const char* fieldName) - { - SimObject *object = Sim::findObject( objectId ); - if( object ) - { - const char *v = object->getDataField(fieldName, ""); - - return dAtof(v); - } - - return false; - } - - void script_simobject_setfield_float(U32 objectId, const char* fieldName, F32 v) - { - SimObject *object = Sim::findObject( objectId ); - if( object ) - { - char buf[256]; - dSprintf(buf, 256, "%g", v ); - object->setDataField(fieldName, "", buf); - } - } - - const char* script_call_namespace_entry_string(Namespace::Entry* entry, S32 argc, const char** argv) - { - // maxArgs improper on a number of console function/methods - if (argc < entry->mMinArgs)// || argc > entry->mMaxArgs) - return ""; - - SimObject* o = NULL; - - if (entry->mNamespace && entry->mNamespace->isClass()) - { - o = Sim::findObject(dAtoi(argv[1])); - if (!o) - return ""; - } - - StringStackConsoleWrapper args(argc, argv); - return entry->cb.mStringCallbackFunc(o, args.count(), args); - } - - bool script_call_namespace_entry_bool(Namespace::Entry* entry, S32 argc, const char** argv) - { - // maxArgs improper on a number of console function/methods - if (argc < entry->mMinArgs)// || argc > entry->mMaxArgs) - return false; - - SimObject* o = NULL; - - if (entry->mNamespace && entry->mNamespace->isClass()) - { - o = Sim::findObject(dAtoi(argv[1])); - if (!o) - return false; - } - - StringStackConsoleWrapper args(argc, argv); - return entry->cb.mBoolCallbackFunc(o, args.count(), args); - } - - S32 script_call_namespace_entry_int(Namespace::Entry* entry, S32 argc, const char** argv) - { - // maxArgs improper on a number of console function/methods - if (argc < entry->mMinArgs)// || argc > entry->mMaxArgs) - return 0; - - SimObject* o = NULL; - - if (entry->mNamespace && entry->mNamespace->isClass()) - { - o = Sim::findObject(dAtoi(argv[1])); - if (!o) - return 0; - } - - StringStackConsoleWrapper args(argc, argv); - return entry->cb.mIntCallbackFunc(o, args.count(), args); - } - - F32 script_call_namespace_entry_float(Namespace::Entry* entry, S32 argc, const char** argv) - { - // maxArgs improper on a number of console function/methods - if (argc < entry->mMinArgs)// || argc > entry->mMaxArgs) - return 0.0f; - - SimObject* o = NULL; - - if (entry->mNamespace && entry->mNamespace->isClass()) - { - o = Sim::findObject(dAtoi(argv[1])); - if (!o) - return 0.0f; - } - - StringStackConsoleWrapper args(argc, argv); - return entry->cb.mFloatCallbackFunc(o, args.count(), args); - } - - - void script_call_namespace_entry_void(Namespace::Entry* entry, S32 argc, const char** argv) - { - // maxArgs improper on a number of console function/methods - if (argc < entry->mMinArgs)// || argc > entry->mMaxArgs) - return; - - SimObject* o = NULL; - - if (entry->mNamespace && entry->mNamespace->isClass()) - { - Sim::findObject(dAtoi(argv[1])); - if (!o) - return; - } - - StringStackConsoleWrapper args(argc, argv); - entry->cb.mVoidCallbackFunc(o, args.count(), args); - } - - S32 script_simobject_get_id(SimObject* so) - { - return so->getId(); - } - - S32 script_simobject_find(const char* classname, const char* name) - { - SimObject *object; - if( Sim::findObject( name, object ) ) - { - // if we specified a classname do type checking - if (classname && dStrlen(classname)) - { - AbstractClassRep* ocr = object->getClassRep(); - while (ocr) - { - if (!dStricmp(ocr->getClassName(), classname)) - return object->getId(); - ocr = ocr->getParentClass(); - } - - } - - // invalid type - return 0; - } - - // didn't find object - return 0; - } - - void script_export_callback_string(StringCallback cb, const char *nameSpace, const char *funcName, const char* usage, S32 minArgs, S32 maxArgs) - { - if (!nameSpace || !dStrlen(nameSpace)) - Con::addCommand(funcName, cb, usage, minArgs + 1, maxArgs + 1); - else - Con::addCommand(nameSpace, funcName, cb, usage, minArgs + 1, maxArgs + 1); - } - - void script_export_callback_void(VoidCallback cb, const char *nameSpace, const char *funcName, const char* usage, S32 minArgs, S32 maxArgs) - { - - if (!nameSpace || !dStrlen(nameSpace)) - Con::addCommand(funcName, cb, usage, minArgs + 1, maxArgs + 1); - else - Con::addCommand(nameSpace, funcName, cb, usage, minArgs + 1, maxArgs + 1); - - - - // example of package support - // note that Parent:: does not work with this, at least not yet anyway - - /* - Namespace* ns; - - StringTableEntry nspace = NULL; - - if (nameSpace && dStrlen(nameSpace)) - nspace = StringTable->insert(nameSpace); - - Namespace::unlinkPackages(); - ns = Namespace::find(nspace, StringTable->insert("fps")); - ns->addCommand(StringTable->insert(funcName), cb, StringTable->insert(usage), minArgs + 1, maxArgs + 1 ); - Namespace::relinkPackages(); - */ - } - - void script_export_callback_bool(BoolCallback cb, const char *nameSpace, const char *funcName, const char* usage, S32 minArgs, S32 maxArgs) - { - if (!nameSpace || !dStrlen(nameSpace)) - Con::addCommand(funcName, cb, usage, minArgs + 1, maxArgs + 1); - else - Con::addCommand(nameSpace, funcName, cb, usage, minArgs + 1, maxArgs + 1); - } - - void script_export_callback_int(IntCallback cb, const char *nameSpace, const char *funcName, const char* usage, S32 minArgs, S32 maxArgs) - { - if (!nameSpace || !dStrlen(nameSpace)) - Con::addCommand(funcName, cb, usage, minArgs + 1, maxArgs + 1); - else - Con::addCommand(nameSpace, funcName, cb, usage, minArgs + 1, maxArgs + 1); - } - - void script_export_callback_float(FloatCallback cb, const char *nameSpace, const char *funcName, const char* usage, S32 minArgs, S32 maxArgs) - { - if (!nameSpace || !dStrlen(nameSpace)) - Con::addCommand(funcName, cb, usage, minArgs + 1, maxArgs + 1); - else - Con::addCommand(nameSpace, funcName, cb, usage, minArgs + 1, maxArgs + 1); - } - - -#ifdef TORQUE_OS_WIN - - void script_input_event(S32 type, S32 value1, S32 value2) - { - if (PlatformWindowManager::get() && PlatformWindowManager::get()->getFirstWindow()) - { - Win32Window* w = (Win32Window*) PlatformWindowManager::get()->getFirstWindow(); - WindowId devId = w->getWindowId(); - - switch (type) - { - case 0: - w->mouseEvent.trigger(devId,0,value1,value2,w->isMouseLocked()); - break; - case 1: - if (value2) - w->buttonEvent.trigger(devId,0,IA_MAKE,value1); - else - w->buttonEvent.trigger(devId,0,IA_BREAK,value1); - break; - - } - - } - - } -#endif - -} - - -DefineEngineStringlyVariadicFunction(TestFunction2Args, const char *, 3, 3, "testFunction(arg1, arg2)") -{ - return "Return Value"; -} diff --git a/Engine/source/cinterface/c_simInterface.cpp b/Engine/source/cinterface/c_simInterface.cpp new file mode 100644 index 000000000..26130a685 --- /dev/null +++ b/Engine/source/cinterface/c_simInterface.cpp @@ -0,0 +1,54 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#include "console/consoleInternal.h" +#include "console/simDatablock.h" +#include "console/simSet.h" +#include "console/engineAPI.h" + +namespace Sim +{ + DefineNewEngineFunction(FindObjectById, SimObject*, (U32 pId), , "") + { + return Sim::findObject(pId); + } + + DefineNewEngineFunction(FindObjectByName, SimObject*, (String pName), , "") + { + return Sim::findObject(StringTable->insert(pName)); + } + + DefineNewEngineFunction(FindDataBlockByName, SimObject*, (String pName), , "") + { + return Sim::getDataBlockGroup()->findObject(StringTable->insert(pName)); + } + + DefineNewEngineFunction(WrapObject, SimObjectPtr*, (SimObject* pObject), , "") + { + return new SimObjectPtr(pObject); + } + + DefineNewEngineFunction(DeleteObjectPtr, void, (SimObjectPtr* pObjectPtr), , "") + { + delete pObjectPtr; + } +} \ No newline at end of file diff --git a/Engine/source/cinterface/c_simdatablockInterface.cpp b/Engine/source/cinterface/c_simdatablockInterface.cpp new file mode 100644 index 000000000..2d7f862a3 --- /dev/null +++ b/Engine/source/cinterface/c_simdatablockInterface.cpp @@ -0,0 +1,40 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#include "console/simDatablock.h" +#include "console/engineAPI.h" + +DefineNewEngineMethod(SimDataBlock, AssignId, void, (),, "") +{ + object->assignId(); +} + +DefineNewEngineMethod(SimDataBlock, Preload, void, (),, "") +{ + static String errorStr; + if (!object->preload(true, errorStr)) + { + Con::errorf(ConsoleLogEntry::General, "Preload failed for %s: %s.", + object->getName(), errorStr.c_str()); + object->deleteObject(); + } +} \ No newline at end of file diff --git a/Engine/source/cinterface/c_simobjectInterface.cpp b/Engine/source/cinterface/c_simobjectInterface.cpp new file mode 100644 index 000000000..757ba243b --- /dev/null +++ b/Engine/source/cinterface/c_simobjectInterface.cpp @@ -0,0 +1,71 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#include "c_simobjectInterface.h" + +#include "console/engineAPI.h" +#include "console/simObject.h" + +DefineNewEngineMethod(SimObject, RegisterObject, bool, (),,"") +{ + return object->registerObject(); +} + +DefineNewEngineMethod(SimObject, GetField, String, (String fieldName, String arrayIndex),, "") +{ + return object->getDataField(StringTable->insert(fieldName), StringTable->insert(arrayIndex)); +} + +DefineNewEngineMethod(SimObject, SetField, void, (String fieldName, String arrayIndex, String value),, "") +{ + object->setDataField(StringTable->insert(fieldName), StringTable->insert(arrayIndex), StringTable->insert(value)); +} + +DefineNewEngineMethod(SimObject, CopyFrom, void, (SimObject* parent),, "") +{ + if (parent) + { + object->setCopySource(parent); + object->assignFieldsFrom(parent); + } +} + +DefineNewEngineMethod(SimObject, SetMods, void, (bool modStaticFields, bool modDynamicFields), , "") +{ + object->setModStaticFields(modStaticFields); + object->setModDynamicFields(modDynamicFields); +} + +DefineNewEngineMethod(SimObject, IsLocked, bool, (), , "") +{ + return object->isLocked(); +} + +DefineNewEngineMethod(SimObject, InspectPreApply, void, (), , "") +{ + object->inspectPreApply(); +} + +DefineNewEngineMethod(SimObject, InspectPostApply, void, (), , "") +{ + object->inspectPostApply(); +} \ No newline at end of file diff --git a/Engine/source/cinterface/cinterface.cpp b/Engine/source/cinterface/cinterface.cpp index 0820b3cf8..e62db2c91 100644 --- a/Engine/source/cinterface/cinterface.cpp +++ b/Engine/source/cinterface/cinterface.cpp @@ -19,449 +19,78 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS // IN THE SOFTWARE. //----------------------------------------------------------------------------- +#include "cinterface.h" -#include "platform/platform.h" #include "console/compiler.h" -#include "console/consoleInternal.h" -#include "console/engineAPI.h" -#include "core/util/tDictionary.h" -#include "core/strings/stringFunctions.h" -#include "app/mainLoop.h" #include "windowManager/platformWindow.h" -#include "windowManager/platformWindowMgr.h" -#ifdef TORQUE_OS_WIN -#include "windowManager/win32/win32Window.h" -#include "windowManager/win32/winDispatch.h" -extern void createFontInit(void); -extern void createFontShutdown(void); -#endif - -#if defined( TORQUE_MINIDUMP ) && defined( TORQUE_RELEASE ) - extern S32 CreateMiniDump(LPEXCEPTION_POINTERS ExceptionInfo); -#endif - -static HashTable gSecureScript; - -extern bool LinkConsoleFunctions; - -extern "C" { - - // reset the engine, unloading any current level and returning to the main menu - void torque_reset() - { - Con::evaluate("disconnect();"); - } - - // initialize Torque 3D including argument handling - S32 torque_engineinit(S32 argc, const char **argv) - { - -#if defined( TORQUE_MINIDUMP ) && defined( TORQUE_RELEASE ) - __try { -#endif - - LinkConsoleFunctions = true; - -#if defined(_MSC_VER) - createFontInit(); -#endif - - // Initialize the subsystems. - StandardMainLoop::init(); - - // Handle any command line args. - if(!StandardMainLoop::handleCommandLine(argc, argv)) - { - Platform::AlertOK("Error", "Failed to initialize game, shutting down."); - return false; - } - -#if defined( TORQUE_MINIDUMP ) && defined( TORQUE_RELEASE ) - } - - __except( CreateMiniDump(GetExceptionInformation()) ) - { - _exit(0); - } -#endif - - return true; - - } - - // tick Torque 3D's main loop - S32 torque_enginetick() - { - -#if defined( TORQUE_MINIDUMP ) && defined( TORQUE_RELEASE ) - __try { -#endif - - bool ret = StandardMainLoop::doMainLoop(); - return ret; - -#if defined( TORQUE_MINIDUMP ) && defined( TORQUE_RELEASE ) - } - __except( CreateMiniDump(GetExceptionInformation()) ) - { - _exit(0); - } -#endif - - - - } - - S32 torque_getreturnstatus() - { - return StandardMainLoop::getReturnStatus(); - } - - // signal an engine shutdown (as with the quit(); console command) - void torque_enginesignalshutdown() - { - Con::evaluate("quit();"); - } - - // shutdown the engine - S32 torque_engineshutdown() - { - -#if defined( TORQUE_MINIDUMP ) && defined( TORQUE_RELEASE ) - __try { -#endif - - // Clean everything up. - StandardMainLoop::shutdown(); - -#if defined(_MSC_VER) - createFontShutdown(); -#endif - -#if defined( TORQUE_MINIDUMP ) && defined( TORQUE_RELEASE ) - } - - __except( CreateMiniDump(GetExceptionInformation()) ) - { - _exit(0); - } -#endif - - // Return. - return true; - - } - - bool torque_isdebugbuild() - { -#ifdef _DEBUG - return true; -#else - return false; -#endif - - } - - S32 torque_getconsolebool(const char* name) - { - return Con::getBoolVariable(name); - } - - void torque_setconsolebool(const char* name, bool value) - { - Con::setBoolVariable(name, value); - } - - static char* gExecutablePath = NULL; - - const char* torque_getexecutablepath() - { - return gExecutablePath; - } - - void torque_setexecutablepath(const char* directory) - { - dsize_t pathLen = dStrlen(directory) + 1; - gExecutablePath = new char[pathLen]; - dStrcpy(gExecutablePath, directory, pathLen); - } - - // set Torque 3D into web deployment mode (disable fullscreen exlusive mode, etc) - void torque_setwebdeployment() - { - Platform::setWebDeployment(true); - } - - // Get a console variable - const char* torque_getvariable(const char* name) - { - return Con::getVariable(StringTable->insert(name)); - } - - // Set a console variable - void torque_setvariable(const char* name, const char* value) - { - Con::setVariable(StringTable->insert(name), StringTable->insert(value)); - } - - static Namespace::Entry* GetEntry(const char* nameSpace, const char* name) - { - Namespace* ns = NULL; - - if (!nameSpace || !dStrlen(nameSpace)) - ns = Namespace::mGlobalNamespace; - else - { - nameSpace = StringTable->insert(nameSpace); - ns = Namespace::find(nameSpace); //can specify a package here, maybe need, maybe not - } - - if (!ns) - return NULL; - - name = StringTable->insert(name); - - Namespace::Entry* entry = ns->lookupRecursive(name); - - return entry; - } - - // Export a function to the Torque 3D console system which matches the StringCallback function prototype - // specify the nameSpace, functionName, usage, min and max arguments - void torque_exportstringcallback(StringCallback cb, const char *nameSpace, const char *funcName, const char* usage, S32 minArgs, S32 maxArgs) - { - if (!nameSpace || !dStrlen(nameSpace)) - Con::addCommand(funcName, cb, usage, minArgs + 1, maxArgs + 1); - else - Con::addCommand(nameSpace, funcName, cb, usage, minArgs + 1, maxArgs + 1); - } - - void torque_callvoidfunction(const char* nameSpace, const char* name, S32 argc, const char ** argv) - { - - Namespace::Entry* entry = GetEntry(nameSpace, name); - - if (!entry) - return; - - StringStackConsoleWrapper args(argc, argv); - entry->cb.mVoidCallbackFunc(NULL, args.count(), args); - } - - F32 torque_callfloatfunction(const char* nameSpace, const char* name, S32 argc, const char ** argv) - { - - Namespace::Entry* entry = GetEntry(nameSpace, name); - - if (!entry) - return 0.0f; - - StringStackConsoleWrapper args(argc, argv); - return entry->cb.mFloatCallbackFunc(NULL, args.count(), args); - } - - S32 torque_callintfunction(const char* nameSpace, const char* name, S32 argc, const char ** argv) - { - - Namespace::Entry* entry = GetEntry(nameSpace, name); - - if (!entry) - return 0; - - StringStackConsoleWrapper args(argc, argv); - return entry->cb.mIntCallbackFunc(NULL, args.count(), args); - } - - - const char * torque_callstringfunction(const char* nameSpace, const char* name, S32 argc, const char ** argv) - { - Namespace::Entry* entry = GetEntry(nameSpace, name); - - if (!entry) - return ""; - - StringStackConsoleWrapper args(argc, argv); - return entry->cb.mStringCallbackFunc(NULL, args.count(), args); - } - - bool torque_callboolfunction(const char* nameSpace, const char* name, S32 argc, const char ** argv) - { - Namespace::Entry* entry = GetEntry(nameSpace, name); - - if (!entry) - return false; - - StringStackConsoleWrapper args(argc, argv); - return entry->cb.mBoolCallbackFunc(NULL, args.count(), args); - } - - - const char * torque_callscriptfunction(const char* nameSpace, const char* name, S32 argc, const char ** argv) - { - Namespace::Entry* entry = GetEntry(nameSpace, name); - - if (!entry) - return ""; - - if(!entry->mFunctionOffset) - return ""; - - StringStackConsoleWrapper args(argc, argv); - const char* ret = entry->mCode->exec(entry->mFunctionOffset, StringTable->insert(name), entry->mNamespace, args.count(), args, false, entry->mPackage); - - if (!ret || !dStrlen(ret)) - return ""; - - return ret; - - } - - - // Call a TorqueScript console function that has been marked as secure - const char* torque_callsecurefunction(const char* nameSpace, const char* name, S32 argc, const char ** argv) - { - static const char* invalidChars = "()=:{}"; - String s = nameSpace; - s += "::"; - s += name; - s = String::ToUpper(s); - - if (!gSecureScript.count(StringTable->insert(s.c_str()))) - { - Con::warnf("\nAttempt to call insecure script: %s\n", s.c_str()); - return ""; - } - - // scan through for invalid characters - for (S32 i = 0; i < argc ; i++) - for (S32 j = 0; j < dStrlen(invalidChars) ; j++) - for (S32 k = 0; k < dStrlen(argv[i]); k++) - if (invalidChars[j] == argv[i][k]) - { - Con::warnf("\nInvalid parameter passed to secure script: %s, %s\n", s.c_str(), argv[i]); - return ""; - } - - Namespace::Entry* entry = GetEntry(nameSpace, name); - - if (!entry) - return ""; - - static char returnBuffer[32]; - - switch(entry->mType) - { - case Namespace::Entry::ConsoleFunctionType: - return torque_callscriptfunction(nameSpace, name, argc, argv); - - case Namespace::Entry::StringCallbackType: - return torque_callstringfunction(nameSpace, name, argc, argv); - - case Namespace::Entry::IntCallbackType: - dSprintf(returnBuffer, sizeof(returnBuffer), "%d", torque_callintfunction(nameSpace, name, argc, argv)); - return returnBuffer; - - case Namespace::Entry::FloatCallbackType: - dSprintf(returnBuffer, sizeof(returnBuffer), "%g", torque_callfloatfunction(nameSpace, name, argc, argv)); - return returnBuffer; - - case Namespace::Entry::VoidCallbackType: - torque_callvoidfunction(nameSpace, name, argc, argv); - return ""; - - case Namespace::Entry::BoolCallbackType: - dSprintf(returnBuffer, sizeof(returnBuffer), "%d", (U32) torque_callboolfunction(nameSpace, name, argc, argv)); - return returnBuffer; - }; - - return ""; - - } - - // Set a TorqueScript console function as secure and available for JavaScript via the callScript plugin method - void torque_addsecurefunction(const char* nameSpace, const char* fname) - { - String s = nameSpace; - s += "::"; - s += fname; - s = String::ToUpper(s); - - gSecureScript.insertEqual(StringTable->insert(s.c_str()), StringTable->insert(s.c_str())); - } - - - // Evaluate arbitrary TorqueScript (ONLY CALL torque_evaluate FROM TRUSTED CODE!!!) - const char* torque_evaluate(const char* code) - { - return Con::evaluate(code); - } - - // resize the Torque 3D child window to the specified width and height - void torque_resizewindow(S32 width, S32 height) - { - if (PlatformWindowManager::get() && PlatformWindowManager::get()->getFirstWindow()) - PlatformWindowManager::get()->getFirstWindow()->setSize(Point2I(width,height)); - } - -#if defined(TORQUE_OS_WIN) && !defined(TORQUE_SDL) - // retrieve the hwnd of our render window - void* torque_gethwnd() - { - if (PlatformWindowManager::get() && PlatformWindowManager::get()->getFirstWindow()) - { - Win32Window* w = (Win32Window*) PlatformWindowManager::get()->getFirstWindow(); - return (void *) w->getHWND(); - } - - return NULL; - } - - // directly add a message to the Torque 3D event queue, bypassing the Windows event queue - // this is useful in the case of the IE plugin, where we are hooking into an application - // level message, and posting to the windows queue would cause a hang - void torque_directmessage(U32 message, U32 wparam, U32 lparam) - { - if (PlatformWindowManager::get() && PlatformWindowManager::get()->getFirstWindow()) - { - Win32Window* w = (Win32Window*) PlatformWindowManager::get()->getFirstWindow(); - Dispatch(DelayedDispatch,w->getHWND(),message,wparam,lparam); - } - } - -#endif -} - -// This function is solely to test the TorqueScript <-> Javascript binding -// By default, it is marked as secure by the web plugins and then can be called from -// Javascript on the web page to ensure that function calls across the language -// boundry are working with arguments and return values -DefineEngineFunction( testJavaScriptBridge, const char *, (const char* arg1, const char* arg2, const char* arg3), , "testBridge(arg1, arg2, arg3)") +CInterface& CInterface::GetCInterface() { - S32 failed = 0; - if (dStrcmp(arg1,"one")) - failed = 2; - if (dStrcmp(arg2,"two")) - failed = 2; - if (dStrcmp(arg3,"three")) - failed = 2; - - - //attempt to call from TorqueScript -> JavaScript - const char* jret = Con::evaluate("JS::bridgeCallback(\"one\",\"two\",\"three\");"); - - if (dStrcmp(jret,"42")) - failed = 3; - - static const U32 bufSize = 256; - char *ret = Con::getReturnBuffer(bufSize); - - dSprintf(ret, bufSize, "%i", failed); - - return ret; + static CInterface INSTANCE; + return INSTANCE; } +bool CInterface::isMethod(const char* className, const char* methodName) +{ + return GetCInterface()._isMethod(className, methodName); +} +const char* CInterface::CallFunction(const char* nameSpace, const char* name, const char **argv, int argc, bool *result) +{ + return GetCInterface()._CallFunction(nameSpace, name, argv, argc, result); +} +const char* CInterface::CallMethod(SimObject* obj, const char* name, const char **argv, int argc, bool *res) +{ + return GetCInterface()._CallMethod(obj->getClassName(), obj->getClassNamespace(), obj->getId(), name, argv, argc, res); +} +void CInterface::CallMain(bool *res) +{ + GetCInterface()._CallMain(res); +} +bool CInterface::_isMethod(const char* className, const char* methodName) const +{ + if (mIsMethodCallback) + return mIsMethodCallback(className, methodName); + + return NULL; +} + +const char* CInterface::_CallFunction(const char* nameSpace, const char* name, const char **argv, int argc, bool *result) const +{ + if (mFunctionCallback) + return mFunctionCallback(nameSpace, name, argv, argc, result); + + *result = false; + return NULL; +} + +const char* CInterface::_CallMethod(const char* className, const char* classNamespace, U32 object, const char* name, const char **argv, int argc, bool *res) const +{ + if (mMethodCallback) + return mMethodCallback(className, classNamespace, object, name, argv, argc, res); + + *res = false; + return NULL; +} + +void CInterface::_CallMain(bool *res) const +{ + if (mMainCallback) + { + *res = true; + mMainCallback(); + return; + } + + *res = false; +} + +TORQUE_API void SetCallbacks(void* ptr, void* methodPtr, void* isMethodPtr, void* mainPtr) { + CInterface::GetCInterface().SetCallFunctionCallback(ptr); + CInterface::GetCInterface().SetCallMethodCallback(methodPtr); + CInterface::GetCInterface().SetCallIsMethodCallback(isMethodPtr); + CInterface::GetCInterface().SetMainCallback(mainPtr); +} \ No newline at end of file diff --git a/Engine/source/cinterface/cinterface.h b/Engine/source/cinterface/cinterface.h index d7f839331..a1dcbcc9e 100644 --- a/Engine/source/cinterface/cinterface.h +++ b/Engine/source/cinterface/cinterface.h @@ -21,10 +21,41 @@ //----------------------------------------------------------------------------- #pragma once +#include "platform/platformDlibrary.h" +#include "console/engineAPI.h" +#include "console/simBase.h" -// cinterface can override this (useful for plugins, etc) -extern "C" { +#define CALL_CINTERFACE_FUNCTION(name, ...){const char *v[] = { __VA_ARGS__ }; CInterface::CallFunction(name, v, sizeof(v) / sizeof(*v));} -const char* torque_getexecutablepath(); +class CInterface { + typedef bool(*IsMethodCallback)(const char* className, const char* methodName); + typedef void(*CallMainCallback)(); + typedef const char* (*CallFunctionCallback)(const char* nameSpace, const char* name, const char **argv, int argc, bool *result); + typedef const char* (*CallMethodCallback)(const char* className, const char* classNamespace, U32 object, const char* name, const char **argv, int argc, bool *result); + IsMethodCallback mIsMethodCallback; + CallFunctionCallback mFunctionCallback; + CallMethodCallback mMethodCallback; + CallMainCallback mMainCallback; + const char* _CallFunction(const char* nameSpace, const char* name, const char **argv, int argc, bool *result) const; + const char* _CallMethod(const char* className, const char* classNamespace, U32 object, const char* name, const char **argv, int argc, bool *res) const; + void _CallMain(bool *res) const; + bool _isMethod(const char* className, const char* methodName) const; +public: + CInterface() + { + mFunctionCallback = NULL; + mMethodCallback = NULL; + mIsMethodCallback = NULL; + mMainCallback = NULL; + } -} + static const char* CallFunction(const char* nameSpace, const char* name, const char **argv, int argc, bool *result); + static const char* CallMethod(SimObject* obj, const char* name, const char **argv, int argc, bool *res); + static void CallMain(bool *res); + static bool isMethod(const char* className, const char* methodName); + static CInterface& GetCInterface(); + void SetCallFunctionCallback(void* ptr) { mFunctionCallback = (CallFunctionCallback)ptr; }; + void SetCallMethodCallback(void* ptr) { mMethodCallback = (CallMethodCallback)ptr; }; + void SetCallIsMethodCallback(void* ptr) { mIsMethodCallback = (IsMethodCallback)ptr; }; + void SetMainCallback(void* ptr) { mMainCallback = (CallMainCallback)ptr; }; +}; \ No newline at end of file diff --git a/Engine/source/platformMac/macFileIO.mm b/Engine/source/platformMac/macFileIO.mm index 767dbca8e..e4d182dc1 100644 --- a/Engine/source/platformMac/macFileIO.mm +++ b/Engine/source/platformMac/macFileIO.mm @@ -37,7 +37,7 @@ #import "core/strings/stringFunctions.h" #import "console/console.h" #import "platform/profiler.h" -#import "cinterface/cinterface.h" +#import "cinterface/c_controlInterface.h" #import "core/volume.h" //TODO: file io still needs some work... From 870ee9fb5be96b01929f2bb0ea69d259737bc729 Mon Sep 17 00:00:00 2001 From: Lukas Joergensen Date: Sat, 21 Apr 2018 10:24:41 +0200 Subject: [PATCH 2/3] Integrate new CInterface into the engine-console --- Engine/source/app/mainLoop.cpp | 6 +++++ Engine/source/cinterface/c_simInterface.cpp | 5 ++-- .../cinterface/c_simobjectInterface.cpp | 2 -- Engine/source/console/codeInterpreter.cpp | 27 ++++++++++++++++--- Engine/source/console/console.cpp | 26 ++++++++++++++++++ Engine/source/module/moduleManager.cpp | 9 +++++++ 6 files changed, 67 insertions(+), 8 deletions(-) diff --git a/Engine/source/app/mainLoop.cpp b/Engine/source/app/mainLoop.cpp index 36998169f..ea2322d81 100644 --- a/Engine/source/app/mainLoop.cpp +++ b/Engine/source/app/mainLoop.cpp @@ -61,6 +61,7 @@ // For the TickMs define... fix this for T2D... #include "T3D/gameBase/processList.h" +#include "cinterface/cinterface.h" #ifdef TORQUE_ENABLE_VFS #include "platform/platformVFS.h" @@ -443,6 +444,11 @@ bool StandardMainLoop::handleCommandLine( S32 argc, const char **argv ) // directly because the resource system restricts // access to the "root" directory. + bool foundExternalMain = false; + CInterface::CallMain(&foundExternalMain); + if (foundExternalMain) + return true; + #ifdef TORQUE_ENABLE_VFS Zip::ZipArchive *vfs = openEmbeddedVFSArchive(); bool useVFS = vfs != NULL; diff --git a/Engine/source/cinterface/c_simInterface.cpp b/Engine/source/cinterface/c_simInterface.cpp index 26130a685..d3b0ea58f 100644 --- a/Engine/source/cinterface/c_simInterface.cpp +++ b/Engine/source/cinterface/c_simInterface.cpp @@ -42,12 +42,13 @@ namespace Sim return Sim::getDataBlockGroup()->findObject(StringTable->insert(pName)); } - DefineNewEngineFunction(WrapObject, SimObjectPtr*, (SimObject* pObject), , "") + // EngineAPI doesn't work with SimObjectPtr + TORQUE_API SimObjectPtr* fnWrapObject (SimObject* pObject) { return new SimObjectPtr(pObject); } - DefineNewEngineFunction(DeleteObjectPtr, void, (SimObjectPtr* pObjectPtr), , "") + TORQUE_API void fnDeleteObjectPtr(SimObjectPtr* pObjectPtr) { delete pObjectPtr; } diff --git a/Engine/source/cinterface/c_simobjectInterface.cpp b/Engine/source/cinterface/c_simobjectInterface.cpp index 757ba243b..4c018c0ab 100644 --- a/Engine/source/cinterface/c_simobjectInterface.cpp +++ b/Engine/source/cinterface/c_simobjectInterface.cpp @@ -20,8 +20,6 @@ // IN THE SOFTWARE. //----------------------------------------------------------------------------- -#include "c_simobjectInterface.h" - #include "console/engineAPI.h" #include "console/simObject.h" diff --git a/Engine/source/console/codeInterpreter.cpp b/Engine/source/console/codeInterpreter.cpp index 46d58476e..294a14b2b 100644 --- a/Engine/source/console/codeInterpreter.cpp +++ b/Engine/source/console/codeInterpreter.cpp @@ -37,6 +37,7 @@ #include "core/strings/stringUnit.h" #include "console/console.h" #include "console/consoleInternal.h" +#include "cinterface/cinterface.h" //#define TORQUE_VALIDATE_STACK @@ -2023,7 +2024,7 @@ OPCodeReturn CodeInterpreter::op_callfunc_resolve(U32 &ip) // Try to look it up. mNSEntry = Namespace::find(fnNamespace)->lookup(fnName); - if (!mNSEntry) + if (!CInterface::GetCInterface().isMethod(fnNamespace, fnName) && !mNSEntry) { ip += 5; Con::warnf(ConsoleLogEntry::General, @@ -2051,6 +2052,7 @@ OPCodeReturn CodeInterpreter::op_callfunc(U32 &ip) U32 *code = mCodeBlock->code; + StringTableEntry fnNamespace = CodeToSTE(mCodeBlock->code, ip + 2); StringTableEntry fnName = CodeToSTE(code, ip); //if this is called from inside a function, append the ip and codeptr @@ -2068,10 +2070,16 @@ OPCodeReturn CodeInterpreter::op_callfunc(U32 &ip) const char *componentReturnValue = ""; Namespace *ns = NULL; + bool cFunctionRes = false; + const char* cRetRes = NULL; + if (callType == FuncCallExprNode::FunctionCall) { if (!mNSEntry) mNSEntry = Namespace::global()->lookup(fnName); + + StringStackWrapper args(mCallArgc, mCallArgv); + cRetRes = CInterface::GetCInterface().CallFunction(fnNamespace, fnName, args.argv, args.argc, &cFunctionRes); } else if (callType == FuncCallExprNode::MethodCall) { @@ -2102,6 +2110,9 @@ OPCodeReturn CodeInterpreter::op_callfunc(U32 &ip) mNSEntry = ns->lookup(fnName); else mNSEntry = NULL; + + StringStackWrapper args(mCallArgc, mCallArgv); + cRetRes = CInterface::GetCInterface().CallMethod(gEvalState.thisObject, fnName, args.argv, args.argc, &cFunctionRes); } else // it's a ParentCall { @@ -2128,7 +2139,7 @@ OPCodeReturn CodeInterpreter::op_callfunc(U32 &ip) nsUsage = mNSEntry->mUsage; routingId = 0; } - if (!mNSEntry || mExec.noCalls) + if (!cFunctionRes && (!mNSEntry || mExec.noCalls)) { if (!mExec.noCalls && !(routingId == MethodOnComponent)) { @@ -2152,11 +2163,19 @@ OPCodeReturn CodeInterpreter::op_callfunc(U32 &ip) // ConsoleFunctionType is for any function defined by script. // Any 'callback' type is an engine function that is exposed to script. - if (mNSEntry->mType == Namespace::Entry::ConsoleFunctionType) + if (mNSEntry->mType == Namespace::Entry::ConsoleFunctionType + || cFunctionRes) { ConsoleValueRef ret; - if (mNSEntry->mFunctionOffset) + if (cFunctionRes) + { + StringStackConsoleWrapper retVal(1, &cRetRes); + ret = retVal.argv[0]; + } + else if (mNSEntry->mFunctionOffset) + { ret = mNSEntry->mCode->exec(mNSEntry->mFunctionOffset, fnName, mNSEntry->mNamespace, mCallArgc, mCallArgv, false, mNSEntry->mPackage); + } STR.popFrame(); // Functions are assumed to return strings, so look ahead to see if we can skip the conversion diff --git a/Engine/source/console/console.cpp b/Engine/source/console/console.cpp index 55880f30f..eab14bbf8 100644 --- a/Engine/source/console/console.cpp +++ b/Engine/source/console/console.cpp @@ -40,6 +40,7 @@ #include #include "platform/threads/mutex.h" #include "core/util/journal/journal.h" +#include "cinterface/cinterface.h" extern StringStack STR; extern ConsoleValueStack CSTK; @@ -1488,6 +1489,18 @@ ConsoleValueRef evaluatef(const char* string, ...) // Internal execute for global function which does not save the stack ConsoleValueRef _internalExecute(S32 argc, ConsoleValueRef argv[]) { + const char** argv_str = static_cast(malloc((argc - 1) * sizeof(char *))); + for (int i = 0; i < argc - 1; i++) + { + argv_str[i] = argv[i + 1]; + } + bool result; + const char* methodRes = CInterface::CallFunction(NULL, argv[0], argv_str, argc - 1, &result); + if (result) + { + return ConsoleValueRef::fromValue(CSTK.pushString(methodRes)); + } + Namespace::Entry *ent; StringTableEntry funcName = StringTable->insert(argv[0]); ent = Namespace::global()->lookup(funcName); @@ -1559,6 +1572,18 @@ ConsoleValueRef _internalExecute(SimObject *object, S32 argc, ConsoleValueRef ar } } + const char** argv_str = static_cast(malloc((argc - 2) * sizeof(char *))); + for (int i = 0; i < argc - 2; i++) + { + argv_str[i] = argv[i + 2]; + } + bool result; + const char* methodRes = CInterface::CallMethod(object, argv[0], argv_str, argc - 2, &result); + if (result) + { + return ConsoleValueRef::fromValue(CSTK.pushString(methodRes)); + } + if(object->getNamespace()) { U32 ident = object->getId(); @@ -1655,6 +1680,7 @@ inline ConsoleValueRef _executef(S32 checkArgc, S32 argc, ConsoleValueRef *argv) //------------------------------------------------------------------------------ bool isFunction(const char *fn) { + if (CInterface::isMethod(NULL, fn)) return true; const char *string = StringTable->lookup(fn); if(!string) return false; diff --git a/Engine/source/module/moduleManager.cpp b/Engine/source/module/moduleManager.cpp index ec45ad918..c5d3b42f6 100644 --- a/Engine/source/module/moduleManager.cpp +++ b/Engine/source/module/moduleManager.cpp @@ -455,6 +455,15 @@ bool ModuleManager::loadModuleGroup( const char* pModuleGroup ) moduleGroup, pLoadReadyModuleDefinition->getModuleId(), pLoadReadyModuleDefinition->getVersionId(), pLoadReadyModuleDefinition->getModuleScriptFilePath() ); } } + else + { + // Is the create method available? + if (pScopeSet->isMethod(pLoadReadyModuleDefinition->getCreateFunction())) + { + // Yes, so call the create method. + Con::executef(pScopeSet, pLoadReadyModuleDefinition->getCreateFunction()); + } + } // Raise notifications. raiseModulePostLoadNotifications( pLoadReadyModuleDefinition ); From 6ebb05749eab000b284fcd36d87e86248912b3ba Mon Sep 17 00:00:00 2001 From: Lukas Joergensen Date: Sat, 21 Apr 2018 10:26:20 +0200 Subject: [PATCH 3/3] Don't automatically register objects, allow for modifications to the intial fields before register. This is necessary in order to set the fields before initialization such as TorqueScript does --- Engine/source/console/simObject.h | 1 - 1 file changed, 1 deletion(-) diff --git a/Engine/source/console/simObject.h b/Engine/source/console/simObject.h index 2119ea6a9..1fb30a0ef 100644 --- a/Engine/source/console/simObject.h +++ b/Engine/source/console/simObject.h @@ -455,7 +455,6 @@ class SimObject: public ConsoleObject, public TamlCallbacks { T* object = new T; object->incRefCount(); - object->registerObject(); return object; }