engine.cpp

engine.cpp

Rate This
  • Comments 1

#include "headers.h"

ScriptEngine::ScriptEngine()
{
    DLLAddRef();

    this->m_cref = 1;
    this->m_thread = threadNone;
    this->m_state = SCRIPTSTATE_UNINITIALIZED;
    this->m_psite = NULL;
    this->m_pNamedItemList = NULL;
}

ScriptEngine::~ScriptEngine()
{
    Assert(this->m_cref == 0);

    if (this->m_state != SCRIPTSTATE_CLOSED && this->m_state != SCRIPTSTATE_UNINITIALIZED)
    {
        Bug("It's a very bad idea to deallocate an initialized engine.");
    }

    this->Close();
    if (NULL != this->m_pNamedItemList)
        delete this->m_pNamedItemList;

    DLLRelease();
}

HRESULT ScriptEngine::Create(ScriptEngine * * ppEngine)
{
    AssertOutPtr(ppEngine);

    HRESULT hr;

    *ppEngine = NULL;
    ScriptEngine * pEngine = NULL;

    pEngine = new ScriptEngine();
    if (NULL == pEngine)
    {
        hr = E_OUTOFMEMORY;
        goto LError;
    }

    hr = NamedItemList::Create(23, &pEngine->m_pNamedItemList);
    if (FAILED(hr))
        goto LError;

    *ppEngine = pEngine;
    pEngine = NULL;

    hr = S_OK;       

LError:

    if (NULL != pEngine)
        pEngine->Release();
       
    return hr;
}

void ScriptEngine::ChangeScriptState(SCRIPTSTATE state)
{
    if (this->m_state != state)
    {
        this->m_state = state;
        if (this->m_psite != NULL)
            this->m_psite->OnStateChange(state);
    }
}

BOOL ScriptEngine::IsInitialized(void)
{
    switch(this->m_state)
    {
    case SCRIPTSTATE_CLOSED:
    case SCRIPTSTATE_UNINITIALIZED:
        Assert(NULL == this->m_psite);
        Assert(threadNone == this->m_thread);
        return FALSE;
    case SCRIPTSTATE_INITIALIZED:
    case SCRIPTSTATE_STARTED:
    case SCRIPTSTATE_CONNECTED:
    case SCRIPTSTATE_DISCONNECTED:
        Assert(threadNone != this->m_thread);
        Assert(NULL != this->m_psite);
        return TRUE;
    default:
        Bug("The script state is a bad value.");
        return FALSE;
    }
}

HRESULT ScriptEngine::VerifyThread(void)
{
    if (this->IsInitialized() && this->m_thread != GetCurrentThreadId())
    {

        Bug("The host is in violation of the script engine threading contract. "
            "Hosts are required to treat the engine as apartment threaded when "
            "the engine is initialized (with some exceptions) and as rental "
            "threaded when it is not initialized.");

        return E_UNEXPECTED;
    }
    return S_OK;
}

HRESULT ScriptEngine::Uninitialize(void)
{
    HRESULT hr;
   
    if (this->m_state == SCRIPTSTATE_CLOSED)
    {
        Bug("It is illegal to move a script engine from CLOSED to UNINITIALIZED");
        // Pointless, too.
        return E_UNEXPECTED;
    }

    if (this->m_state == SCRIPTSTATE_UNINITIALIZED)
        return S_OK;

    hr = this->Initialize();
    if (FAILED(hr))
        goto LError;

    this->m_pNamedItemList->Reset();

    this->m_psite->Release();
    this->m_psite = NULL;
    this->m_thread = threadNone;

    hr = S_OK;

LError:

    return hr;
}

HRESULT ScriptEngine::Initialize(void)
{
    HRESULT hr;
   
    if (!this->IsInitialized())
    {
        Bug("To initialize an uninitialized engine, call SetScriptSite.");
        return E_UNEXPECTED;
    }

    if (this->m_state == SCRIPTSTATE_INITIALIZED)
        return S_OK;

    if (this->m_state == SCRIPTSTATE_CONNECTED || this->m_state == SCRIPTSTATE_DISCONNECTED)
    {
        hr = this->FullyDisconnectEventSinks();
        if (FAILED(hr))
            goto LError;
    }

    hr = this->StopEngine();
    if (FAILED(hr))
        goto LError;

    hr = S_OK;

LError:

    return hr;
}

HRESULT ScriptEngine::Start(void)
{
    HRESULT hr;

    if (!this->IsInitialized())
    {
        Bug("You cannot start an uninitialized engine.");
        return E_UNEXPECTED;
    }

    if (this->m_state == SCRIPTSTATE_STARTED)
        return S_OK;

    if (this->m_state == SCRIPTSTATE_CONNECTED || this->m_state == SCRIPTSTATE_DISCONNECTED)
    {
        hr = this->FullyDisconnectEventSinks();
        if (FAILED(hr))
            goto LError;
    }

    hr = this->Execute();

    if (SCRIPT_E_REPORTED == hr)
        hr = S_OK;
    if (FAILED(hr))
        goto LError;

    hr = S_OK;

LError:

    return hr;
}

HRESULT ScriptEngine::Execute(void)
{
    // UNDONE
    return S_OK;
}

HRESULT ScriptEngine::StopEngine(void)
{
    // UNDONE
    return S_OK;
}

HRESULT ScriptEngine::Connect(void)
{
    HRESULT hr;

    if (!this->IsInitialized())
    {
        Bug("You cannot connect an uninitialized engine.");
        return E_UNEXPECTED;
    }

    if (this->m_state == SCRIPTSTATE_CONNECTED)
        return S_OK;

    if (this->m_state == SCRIPTSTATE_DISCONNECTED)
    {
        hr = this->ReconnectEventSinks();
        if (FAILED(hr))
            goto LError;
    }
    else
    {
        hr = this->Start();
        if (FAILED(hr))
            goto LError;

        hr = this->ConnectEventSinks();
        if (FAILED(hr))
            goto LError;       
    }

    hr = S_OK;

LError:

    return hr;
}

HRESULT ScriptEngine::TemporarilyDisconnectEventSinks(void)
{
    if (this->m_state == SCRIPTSTATE_DISCONNECTED)
        return S_OK;

    if (this->m_state != SCRIPTSTATE_CONNECTED)
    {
        Bug("You cannot disconnect an engine that is not connected!");
        return E_UNEXPECTED;
    }
   
    // UNDONE
    return S_OK;
}

HRESULT ScriptEngine::FullyDisconnectEventSinks(void)
{
    Assert(this->m_state == SCRIPTSTATE_CONNECTED || this->m_state == SCRIPTSTATE_DISCONNECTED);

    // UNDONE
    return S_OK;
}

HRESULT ScriptEngine::ConnectEventSinks(void)
{
    // UNDONE
    return S_OK;
}

HRESULT ScriptEngine::ReconnectEventSinks(void)
{
    // UNDONE
    return S_OK;
}

// IUnknown

STDMETHODIMP ScriptEngine::QueryInterface(REFIID riid, void * * ppv)
{
    // This method can be called on any thread at any time.
   
    if (NULL == ppv)
    {
        Bug("Null out pointer");
        return E_POINTER;
    }
       
    AssertOutPtr(ppv);

    *ppv = NULL;

    if (IsEqualIID(riid, IID_IUnknown))
        *ppv = (IUnknown *)(IActiveScript *) this;
    else if (IsEqualIID(riid, IID_IActiveScript))
        *ppv = (IActiveScript *) this;
    else if (IsEqualIID(riid, IID_IActiveScriptParse))
        *ppv = (IActiveScriptParse *) this;
    else if (IsEqualIID(riid, IID_IActiveScriptParseProcedure2))
        *ppv = (IActiveScriptParseProcedure2 *) this;
    else if (IsEqualIID(riid, IID_IObjectSafety))
        *ppv = (IObjectSafety *) this;
    else
        return E_NOINTERFACE;

    this->AddRef();
    return S_OK;
}

STDMETHODIMP_(ULONG) ScriptEngine::AddRef(void)
{
    // This method can be called on any thread at any time.
   
    return InterlockedIncrement(&this->m_cref);
}

STDMETHODIMP_(ULONG) ScriptEngine::Release(void)
{
    // This method can be called on any thread at any time,
    // but if this is the final release, the engine should be
    // uninitialized.
   
    long cref = InterlockedDecrement(&this->m_cref);
    if (0 == cref)
        delete this;
    return cref;
}

// IActiveScript

STDMETHODIMP ScriptEngine::SetScriptSite(IActiveScriptSite * psite)
{
    if (NULL == psite)
    {
        Bug("Null site pointer");
        return E_POINTER;
    }

    AssertReadPtr(psite);
   
    if (this->IsInitialized())
    {
        Bug("It is a violation of the script engine contract to set "
            "the site of an engine which is already initialized");
        return E_UNEXPECTED;
    }
       
    psite->AddRef();
    this->m_psite = psite;
    this->m_thread = GetCurrentThreadId();

    this->ChangeScriptState(SCRIPTSTATE_INITIALIZED);

    return S_OK;
}
   
STDMETHODIMP ScriptEngine::GetScriptSite(REFIID riid, void * * ppv)
{
    HRESULT hr;

    if (NULL == ppv)
    {
        Bug("Null out pointer");
        return E_POINTER;
    }

    AssertOutPtr(ppv);

    *ppv = NULL;
   
    hr = this->VerifyThread();
    if (FAILED(hr))
        return hr;

    if (this->m_psite == NULL)
        return S_FALSE;

    return this->m_psite->QueryInterface(riid, ppv);
}

STDMETHODIMP ScriptEngine::SetScriptState(SCRIPTSTATE state)
{
    HRESULT hr;
   
    hr = this->VerifyThread();
    if (FAILED(hr))
        goto LError;
   
    switch(state)
    {
    default:
        Bug("The script state is a bad value.");
        hr = E_INVALIDARG;
        break;
    case SCRIPTSTATE_CLOSED:
        hr = this->Close();
        break;
    case SCRIPTSTATE_UNINITIALIZED:
        hr = this->Uninitialize();
        break;
    case SCRIPTSTATE_INITIALIZED:
        hr = this->Initialize();
        break;
    case SCRIPTSTATE_STARTED:
        hr = this->Start();
        break;
    case SCRIPTSTATE_CONNECTED:
        hr = this->Connect();
        break;
    case SCRIPTSTATE_DISCONNECTED:
        hr = this->TemporarilyDisconnectEventSinks();
        break;
    }

    if (FAILED(hr))
        goto LError;

    this->ChangeScriptState(state);

    hr = S_OK;

LError:

    return hr;
}

STDMETHODIMP ScriptEngine::Close(void)
{
    HRESULT hr;

    if (this->m_state == SCRIPTSTATE_CLOSED)
        return S_OK;

    hr = this->VerifyThread();
    if (FAILED(hr))
        goto LError;

    hr = this->Uninitialize();
    if (FAILED(hr))
        goto LError;

    this->m_pNamedItemList->Clear();

    this->ChangeScriptState(SCRIPTSTATE_CLOSED);

    hr = S_OK;

LError:   

    return hr;
}

STDMETHODIMP ScriptEngine::AddNamedItem(const WCHAR * pszName, DWORD flags)
{

// There are six possible flags.  Suppose the named item is "foo":
//
// SCRIPTITEM_ISVISIBLE     : foo is added to the namespace, so you can call
//                            "foo.bar(123)" from the script
// SCRIPTITEM_ISSOURCE      : foo is an object which sources events
// SCRIPTITEM_GLOBALMEMBERS : calling "bar(123)" calls "foo.bar(123)".  Think
//                            "window.alert()". These guys go into the global module.
// SCRIPTITEM_ISPERSISTENT  : foo survives when we go back to Uninitialized state.
// SCRIPTITEM_CODEONLY      : foo is just the name of a module, not an object
// SCRIPTITEM_NOCODE        : foo is just the name of a named item, not a code module

    HRESULT hr;

    if (NULL == pszName)
        return E_POINTER;

    AssertReadString(pszName);
   
    if (!this->IsInitialized())
    {
        Bug("It is a violation of the script engine contract to add "
            "a named item to an uninitialized engine.");
        return E_UNEXPECTED;
    }

    if ((flags & ~SCRIPTITEM_ALL_FLAGS) != 0)
    {
        Bug("Bad flag passed to AddNamedItem");
        return E_INVALIDARG;
    }

    hr = this->VerifyThread();
    if (FAILED(hr))
        return hr;

    hr = this->m_pNamedItemList->Add(pszName, flags);
    if (FAILED(hr))
        return hr;

    return S_OK;
}

STDMETHODIMP ScriptEngine::AddTypeLib(REFGUID rguid, DWORD major, DWORD minor,
    DWORD flags)
{
    return E_NOTIMPL;
}

STDMETHODIMP ScriptEngine::GetScriptDispatch(const WCHAR * pszName,
    IDispatch * * ppdisp)
{
    return E_NOTIMPL;
}

STDMETHODIMP ScriptEngine::GetScriptState(SCRIPTSTATE * pstate)
{
    return E_NOTIMPL;
}

STDMETHODIMP ScriptEngine::GetCurrentScriptThreadID(SCRIPTTHREADID * pthread)
{
    return E_NOTIMPL;
}

STDMETHODIMP ScriptEngine::GetScriptThreadID(DWORD thread, SCRIPTTHREADID * pthread)
{
    return E_NOTIMPL;
}

STDMETHODIMP ScriptEngine::GetScriptThreadState(SCRIPTTHREADID thread,
    SCRIPTTHREADSTATE * pstate)
{
    return E_NOTIMPL;
}

STDMETHODIMP ScriptEngine::InterruptScriptThread(SCRIPTTHREADID thread,
    const EXCEPINFO * pexcepinfo, DWORD flags)
{
    return E_NOTIMPL;
}

STDMETHODIMP ScriptEngine::Clone(IActiveScript * * ppScriptEngine)
{
    return E_NOTIMPL;
}

// IActiveScriptParse

STDMETHODIMP ScriptEngine::InitNew(void)
{
    return S_OK;
}

STDMETHODIMP ScriptEngine::AddScriptlet(const WCHAR * pszDefaultName,
    const WCHAR * pszCode, const WCHAR * pszItemName, const WCHAR * pszSubItemName,
    const WCHAR * pszEventName, const WCHAR * pszDelimiter, DWORD sourceContext,
    ULONG startingLineNumber, DWORD flags, BSTR * pbstrName, EXCEPINFO * pexcepinfo)
{
    return E_NOTIMPL;
}

STDMETHODIMP ScriptEngine::ParseScriptText(const WCHAR * pszCode,
    const WCHAR * pszItemName, IUnknown *punkContext, const WCHAR * pszDelimiter,
    DWORD sourceContext, ULONG startingLineNumber, DWORD flags,
    VARIANT *pvarResult, EXCEPINFO *pexcepinfo)
{
    return E_NOTIMPL;
}

// IActiveScriptParseProcedure2

STDMETHODIMP ScriptEngine::ParseProcedureText(const WCHAR * pstrCode,
    const WCHAR * pstrFormalParams, const WCHAR * pstrProcedureName,
    const WCHAR * pstrItemName, IUnknown * punkContext, const WCHAR * pstrDelimiter,
    DWORD sourceContext, ULONG startingLineNumber, DWORD flags, IDispatch * * ppdisp)
{
    return E_NOTIMPL;
}

// IObjectSafety

STDMETHODIMP ScriptEngine::GetInterfaceSafetyOptions(REFIID riid,
    DWORD * pSupported, DWORD * pEnabled)
{
    return E_NOTIMPL;
}

STDMETHODIMP ScriptEngine::SetInterfaceSafetyOptions(REFIID riid,
    DWORD mask, DWORD options)
{
    return E_NOTIMPL;
}

 

  • I am using the Script Host to impliment the business logic

    now i am using vb script  for this purpuse

    1. How we can use LINQ comands in parsing in Script Host so i can extends

    my appliction

Page 1 of 1 (1 items)