void PMF::init()

in vm/jitrino/src/main/PMF.cpp [1382:1720]


void PMF::init (bool first_)
{
    assert(!initialized);
    first = first_;
    help_requested = false;
    processVMProperties();
    initialized = true;

#ifdef _DEBUG_PMF
    cout << endl << "Commands received:" << endl;
    for (Cmds::iterator it = cmds.begin(); it != cmds.end(); ++it)
    {
        Cmd& cmd = **it;
        cout << *cmd.left << " = <" << cmd.right << "> " << endl;
    }

    cout << endl << "ActionFactory:" << endl;
    for (IActionFactory* afp = IActionFactory::getFirst(); afp != 0; afp = afp->getNext())
        cout << "  " << afp->getName() << endl;
#endif

    if (first && !help_requested.empty() && !(help_requested == "jit"))
        showHelp(cout);

//  Create common pipeline with empty filter

    pipelines.push_back(new (mm) Pipeline(*this));

//  Process all filter statements
    
    FilterSpecs filterspecs(mm);

    Cmd* cmdp;
    for (Cmds::iterator it = cmds.begin(); it != cmds.end(); ++it)
        if ((cmdp = *it) != 0 && parse(*cmdp, "filter", filterspecs))
        {
            *it = 0;

            if (cmdp->right.empty())
                cmdp->fatal("Empty filter");

            if (cmdp->filtername.empty())
                cmdp->fatal("Invalid filter name");

            if (cmdp->filtername == jitname)
                cmdp->fatal("Invalid filter name - the same as jit name");

            if (filterspecs.find(cmdp->filtername) != filterspecs.end())
                cmdp->fatal("Duplicate filters defined");

            filterspecs[cmdp->filtername] = &cmdp->right;
        }

//  Process all path statements

    for (Cmds::iterator it = cmds.begin(); it != cmds.end(); ++it)
        if ((cmdp = *it) != 0 && parse(*cmdp, "path", filterspecs))
        {
            *it = 0;

            if (!cmdp->filtername.empty() && filterspecs.find(cmdp->filtername) == filterspecs.end())
                continue;

        //  Process left of '=" part

            Str* namep = 0;

            size_t x = cmdp->left->size() - cmdp->xkeyword - 1;
            if (x == 0)
            {
            }
            else if (x == 1)
            {
                Str& name = cmdp->left->at(cmdp->xkeyword + 1);
                if (!name.empty())
                    namep = &name;
            }
            else
                cmdp->fatal("Extra items after path name");

            Pipeline* pipeline = lookup(&cmdp->filtername, true);
            Pipeline::Alias* aliasp = pipeline->lookup(namep);
            if (aliasp == 0)
            {
                aliasp = new (mm) Pipeline::Alias(mm);
                if (namep == 0)
                    pipeline->root = aliasp;
                else
                    aliasp->name = *namep;
                pipeline->aliases->push_back(aliasp);
            }
            else
            {
                cmdp->fatal("Multiple path defined");
            }

        //  Process right of '=" part

            for (StrTokenizer tokens(',', cmdp->right); tokens.next();)
            {
                Pipeline::Alias::Child child;
                child.aliasp = 0;
                child.type = Pipeline::Alias::Child::DEFON;
                if (!tokens.token.empty())
                {
                    char x = tokens.token.ptr[tokens.token.count-1];
                    if (x == '!')
                    {
                        child.type = Pipeline::Alias::Child::REQUIRED;
                        --tokens.token.count;
                    }
                    else if (x == '+')
                    {
                        child.type = Pipeline::Alias::Child::DEFON;
                        --tokens.token.count;
                    }
                    else if (x == '-')
                    {
                        child.type = Pipeline::Alias::Child::DEFOFF;
                        --tokens.token.count;
                    }
                    tokens.token.trim();
                }
                if (tokens.token.empty())
                    cmdp->fatal("Empty path child name");
                child.name = tokens.token;

                aliasp->childs.push_back(child);                
            }
        }

        else if (cmdp != 0 && !cmdp->jitname.empty() && !(cmdp->jitname == jitname))
            *it = 0;    // not for this jit command

//  Process all arg statements

    for (Cmds::iterator it = cmds.begin(); it != cmds.end(); ++it)
        if ((cmdp = *it) != 0 && parse(*cmdp, "arg", filterspecs))
        {
            cmdp->arg = true;
            lookup(&cmdp->filtername, true);
        }

        else if (cmdp != 0 && !cmdp->jitname.empty() && !(cmdp->jitname == jitname))
            *it = 0;    // not for this jit command

//  Path resolution

    Pipeline& compipeline = **pipelines.begin();    // this is the common (empty) pipeline
    if (compipeline.root == 0)
        compipeline.stop("PMF: Invalid common pipeline for '%s' - does not have a root path\n"); 

    for (Pipelines::iterator k = pipelines.begin(); k != pipelines.end(); ++k)
    {
        Pipeline& pipeline = **k;
        Pipeline::Aliases& aliases = *pipeline.aliases;

        if (&pipeline != &compipeline)
        {
            FilterSpecs::iterator it = filterspecs.find(pipeline.name);
            if (it == filterspecs.end())
                pipeline.stop("PMF: Invalid pipeline for '%s.%s' - unspecified filter\n");

            pipeline.method.init(*it->second);
            if (pipeline.method.empty())
                pipeline.stop("PMF: Invalid pipeline for '%s.%s' - empty filter\n");
        }

        if (pipeline.root == 0)
        {
            pipeline.root = new (mm) Pipeline::Alias(mm, *compipeline.root);
            aliases.push_back(pipeline.root);
        }

        for (;;)
        {
            Pipeline::Aliases newaliases(mm);

            for (Pipeline::Aliases::iterator l = aliases.begin(); l != aliases.end(); ++l)
            {
                Pipeline::Alias::Childs::iterator end = (*l)->childs.end(),
                                                  ptr = (*l)->childs.begin();
                for (; ptr != end; ++ptr)
                {
                    ptr->aliasp = pipeline.lookup(&ptr->name);
                    if (ptr->aliasp == 0 && &pipeline != &compipeline)
                    {
                        Pipeline::Alias* comaliasp;
                        if ((comaliasp = compipeline.lookup(&ptr->name)) != 0)
                            newaliases.push_back(new (mm) Pipeline::Alias(mm, *comaliasp));
                    }
                }
            }

            if (newaliases.empty())
                break;
            else
                aliases.insert(aliases.end(), newaliases.begin(), newaliases.end());
        }

        Strs fqname(mm);
        walk(pipeline, pipeline.root, fqname);
    }

//  Build parameters map

    for (Cmds::iterator it = cmds.begin(); it != cmds.end(); ++it)
        if ((cmdp = *it) != 0 && cmdp->arg)
        {
            size_t n = cmdp->left->size() - cmdp->xkeyword - 1;
            if (n == 0)
                cmdp->fatal("No argument name");
        }

    initStreams();

    for (Pipelines::iterator k = pipelines.begin(); k != pipelines.end(); ++k)
    {
        Pipeline& pipeline = **k;
        for (Pipeline::Steps::iterator s = pipeline.steps->begin(); s != pipeline.steps->end(); ++s)
        {
            Pipeline::Step& step = *s;
            step.setup(mm);
        }
    }

//  Create actions for common filter

    for (Pipeline::Steps::iterator s = compipeline.steps->begin(); s != compipeline.steps->end(); ++s)
    {
        Pipeline::Step& step = *s;
        step.action = step.factory->createAction(mm);
        step.reused = false;
    }

//  Create actions for other filters

    for (Pipelines::iterator k = pipelines.begin() + 1; k != pipelines.end(); ++k)
    {
        Pipeline& pipeline = **k;

        for (Pipeline::Steps::iterator s = pipeline.steps->begin(); s != pipeline.steps->end(); ++s)
        {
            Pipeline::Step& step = *s;
            step.action = 0;
            step.reused = false;

        //  Check if this step has any filter-specific agruments
            bool filterspec = false;
            if (step.args != 0)
                for (Args::Store::iterator m = step.args->store.begin(); m != step.args->store.end(); ++m)
                    if (!m->cmdp->filtername.empty())
                    {
                        filterspec = true;
                        break;
                    }

        //  If step doesn't have such arguments, action from common filter can be reused
            if (!filterspec)
                for (Pipeline::Steps::iterator m = compipeline.steps->begin(); m != compipeline.steps->end(); ++m)
                    if (step.factory == m->factory)
                    {
                        step.action = m->action;
                        step.reused = true;
                        break;
                    }

        //  Otherwise action is created and initiated
            if (step.action == 0)
                step.action = step.factory->createAction(mm);
        }
    }

    if (help_requested == "jit" || help_requested == "all")
        showHelpJits(cout);

//  Debug output

#ifdef _DEBUG_PMF
    cout << endl << "PMF jit<" << jitname << ">" << endl;
    for (Pipelines::iterator k = pipelines.begin(); k != pipelines.end(); ++k)
    {
        Pipeline& pipeline = **k;
        cout << "  Pipeline<" << pipeline.name << 
            "> method<" << pipeline.method.classname 
                << "><" << pipeline.method.methodname 
                << "><" << pipeline.method.signature 
            << ">" << endl;

        for (Pipeline::Aliases::iterator l = pipeline.aliases->begin(); l != pipeline.aliases->end(); ++l)
        {
            Pipeline::Alias& alias = **l;
            cout << "    Alias<" << alias.name << ">";
            if (pipeline.root == &alias)
                cout << " *root*";
            cout << endl;

            for (Pipeline::Alias::Childs::iterator m = alias.childs.begin(); m != alias.childs.end(); ++m)
            {
                Pipeline::Alias::Child& child = *m;
                cout << "      Child<" << child.name << "> kind:" << child.type;
                if (child.aliasp!= 0)
                    cout << " to <" << child.aliasp->name << ">";
                cout << endl;
            }
        }

        for (Pipeline::Steps::iterator l = pipeline.steps->begin(); l != pipeline.steps->end(); ++l)
        {
            Pipeline::Step& step = *l;
            cout << "    Step <" << *step.fqname
                 << "> action <" << step.factory->getName()
                 << "> reused:" << step.reused
                 << endl;
            if (step.args != 0)
                for (Args::Store::iterator m = step.args->store.begin(); m != step.args->store.end(); ++m)
                {
                    Args::Arg& arg = *m;
                    cout << "      arg <" << arg.key << "> = <" << arg.value 
                         << "> strength:" << arg.strength
                         << endl;
                }

            if (step.logs != 0)
                for (size_t sid = 0; sid < step.logs->streamidxs.size(); ++sid)
                {
                    size_t idx = step.logs->streamidxs.at(sid);
                    cout << "      sid#" << sid
                         << " idx#" << idx
                         << endl;
                }
        }
    }
#endif

//  Initialize commom pipeline only (others get intialized as need by PipelineIterator)

    compipeline.init();
}