Logo Search packages:      
Sourcecode: whitedune version File versions  Download package

Proto.cpp

/*
 * Proto.cpp
 *
 * Copyright (C) 1999 Stephen F. White
 * 
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program (see the file "COPYING" for details); if 
 * not, write to the Free Software Foundation, Inc., 675 Mass Ave, 
 * Cambridge, MA 02139, USA.
 */

#include <stdio.h>
#include "stdafx.h"

#include "Proto.h"
#include "Scene.h"
#include "EventIn.h"
#include "EventOut.h"
#include "Field.h"
#include "ExposedField.h"
#include "Node.h"

Proto::Proto(Scene *scene, const MyString &name)
{
    _scene = scene;
    _name = name;
    _primaryNode = NULL;
    _nodes = NULL;
}

//Proto::Proto(Proto* proto)
//{
//    Scene                      *_scene;
//    MyString                    _name;
//    Array<EventIn *>            _eventIns;
//    Array<EventOut *>           _eventOuts;
//    Array<Field *>              _fields;
//    Array<ExposedField *>       _exposedFields;
//
//    // for PROTO's:
//    NodeList                   *_nodes;
//    Node                       *_primaryNode;
//}

Proto::~Proto()
{
    int           i;

// the following line would cause a crash when tested with efence
//    for( i = 0; i < _fields.size(); i++) delete _fields[i];
    for( i = 0; i < _eventIns.size(); i++) delete _eventIns[i];
    for( i = 0; i < _eventOuts.size(); i++) delete _eventOuts[i];
    for( i = 0; i < _exposedFields.size(); i++) delete _exposedFields[i];

    if (_primaryNode) _primaryNode->unref();

    if (_nodes) {
      for ( i = 0; i < _nodes->size(); i++) _nodes->get(i)->unref();
    }
    delete _nodes;
}

Node *
Proto::create(Scene *scene)
{
    return new ProtoNode(scene, this);
}

int
Proto::addElement(Element *element)
{
    switch( element->getElementType() ) {
      case EL_FIELD_DEF:
        _fields.append((Field *) element);
        return _fields.size()-1;
      case EL_EVENT_IN:
        _eventIns.append((EventIn *) element);
        break;
      case EL_EVENT_OUT:
        _eventOuts.append((EventOut *) element);
        break;
      case EL_EXPOSED_FIELD:
      return addExposedField((ExposedField *) element);
      default:
        _scene->errorf("internal error:  unexpected element in Proto");
        break;
    }
    return -1;
}

int
Proto::addField(int fieldType, const MyString &name, FieldValue *defaultValue,
            FieldValue *min, FieldValue *max)
{
    _fields.append(new Field(fieldType, name, defaultValue, NULL,
                       min, max, ANY_NODE));
    return _fields.size()-1;
}

int
Proto::addField(int fieldType, const MyString &name, FieldValue *defaultValue,
              int nodeType)
{
    _fields.append(new Field(fieldType, name, defaultValue, NULL,
                       NULL, NULL, nodeType));
    return _fields.size()-1;
}

int
Proto::addField(int fieldType, const MyString &name, FieldValue *defaultValue,
              int flags, const char **strings)
{
    _fields.append(new Field(fieldType, name, defaultValue, NULL,
                       NULL, NULL, ANY_NODE, flags, strings));
    return _fields.size()-1;
}

void
Proto::addEventIn(int fieldType, const MyString &name)
{
    _eventIns.append(new EventIn(fieldType, name));
}

void
Proto::addEventIn(int fieldType, const MyString &name, int flags)
{
    _eventIns.append(new EventIn(fieldType, name, flags));
}

void
Proto::addEventIn(int fieldType, const MyString &name, int flags, int field)
{
    _eventIns.append(new EventIn(fieldType, name, flags));
    _eventIns[_eventIns.size() - 1]->setField(field); 
    _fields[field]->setEventIn(_eventIns.size() - 1);
}

void
Proto::addEventOut(int fieldType, const MyString &name)
{
    _eventOuts.append(new EventOut(fieldType, name));
}

void
Proto::addEventOut(int fieldType, const MyString &name, int flags)
{
    _eventOuts.append(new EventOut(fieldType, name, flags));
}

int
Proto::addExposedField(int fieldType, const MyString &name,
                       FieldValue *defaultValue, 
                       FieldValue *min, FieldValue *max)
{
    return addExposedField(new ExposedField(fieldType, name,
                                          defaultValue, min, max));
}

int
Proto::addExposedField(int fieldType, const MyString &name,
                   FieldValue *defaultValue, int nodeType)
{
    return addExposedField(new ExposedField(fieldType, name,
                                          defaultValue, NULL, NULL, 
                                            nodeType));
}

int
Proto::addExposedField(int fieldType, const MyString &name,
                   FieldValue *defaultValue, int flags, 
                       const char **strings)
{
    return addExposedField(new ExposedField(fieldType, name,
                                    defaultValue, NULL, NULL, 0, flags, 
                                    strings));
}

int
Proto::addExposedField(ExposedField *exposedField)
{
    const MyString &name = exposedField->getName();
    int            type = exposedField->getType();
    FieldValue  *value = exposedField->getValue();
    FieldValue  *min = exposedField->getMin();
    FieldValue    *max = exposedField->getMax();
    int            flags = exposedField->getFlags();
    int            nodeType = exposedField->getNodeType();
    const char **strings = exposedField->getStrings();

    _exposedFields.append(exposedField);

    // now add a hidden Field with the same name
    _fields.append(new Field(type, name, value, exposedField, min, max, 
                       nodeType, FF_HIDDEN | flags, strings));

    exposedField->setField(_fields.size() - 1);

    // now add a hidden EventIn called set_<name>
    char          buf[1024];
    sprintf(buf, "set_%s", (const char *) name);
    _eventIns.append(new EventIn(type, buf, flags, exposedField));

    exposedField->setEventIn(_eventIns.size() - 1);
    // now add a hidden EventOut called <name>_changed
    sprintf(buf, "%s_changed", (const char *) name);
    _eventOuts.append(new EventOut(type, buf, flags, exposedField));

    exposedField->setEventOut(_eventOuts.size() - 1);

    return _fields.size()-1;
}

int
Proto::lookupSimpleEventIn(const MyString &name) const
{
    for (int i = 0; i < _eventIns.size(); i++)
      if (_eventIns[i]->getName() == name) return i;

    return INVALID_INDEX;
}

int
Proto::lookupEventIn(const MyString &name) const
{
    int           index;

    if ((index = lookupSimpleEventIn(name)) == INVALID_INDEX)
    {
      // simple search failed; look for an exposedField
      if ((index = lookupExposedField(name)) != INVALID_INDEX) {

          // now look up the corresponding eventIn
          char          buf[1024];
          sprintf(buf, "set_%s", (const char *) name);
          index = lookupSimpleEventIn(buf);
      }
    }
    return index;
}

int
Proto::lookupSimpleEventOut(const MyString &name) const
{
    for (int i = 0; i < _eventOuts.size(); i++)
      if (_eventOuts[i]->getName() == name)
          return i;

    return INVALID_INDEX;
}

int
Proto::lookupEventOut(const MyString &name) const
{
    int           index;

    if ((index = lookupSimpleEventOut(name)) == INVALID_INDEX)
    {
      // simple search failed; look for an exposedField
      if ((index = lookupExposedField(name)) != INVALID_INDEX) {

          // now look up the corresponding eventOut
          char          buf[1024];
          sprintf(buf, "%s_changed", (const char *) name);
          index = lookupSimpleEventOut(buf);
      }
    }
    return index;
}

int
Proto::lookupField(const MyString &name) const
{
    for (int i = 0; i < _fields.size(); i++)
      if (_fields[i]->getName() == name)
          return i;

    return INVALID_INDEX;
}

int
Proto::lookupExposedField(const MyString &name) const
{
    for (int i = 0; i < _exposedFields.size(); i++)
      if (_exposedFields[i]->getName() == name)
          return i;

    return INVALID_INDEX;
}


int Proto::write(int f, int indent) const
{
    int           i;

    for (i = 0; i < _fields.size(); i++)
      RET_ONERROR( _fields[i]->write(f, indent) )
    for (i = 0; i < _eventIns.size(); i++)
      RET_ONERROR( _eventIns[i]->write(f, indent) )
    for (i = 0; i < _eventOuts.size(); i++)
      RET_ONERROR( _eventOuts[i]->write(f, indent) )
    for (i = 0; i < _exposedFields.size(); i++)
      RET_ONERROR( _exposedFields[i]->write(f, indent) )
    return(0);
}

int Proto::writeWithoutFields(int f, int indent) const
{
    int           i;

    for (i = 0; i < _eventIns.size(); i++)
      RET_ONERROR( _eventIns[i]->write(f, indent) )
    for (i = 0; i < _eventOuts.size(); i++)
      RET_ONERROR( _eventOuts[i]->write(f, indent) )
    for (i = 0; i < _exposedFields.size(); i++)
      RET_ONERROR( _exposedFields[i]->write(f, indent) )
    return(0);
}

void
Proto::define(Node *primaryNode, NodeList *nodes)
{
    _primaryNode = primaryNode;
    _primaryNode->ref();
    _nodes = nodes;
    if (_nodes) {
      for ( int i = 0; i < _nodes->size(); i++) _nodes->get(i)->ref();
    }
}


int Proto::write_define(int f, int indent) const
{
//   RET_ONERROR( _primaryNode->write(f, indent) )
//   RET_ONERROR( _scene->write(f,indent) )
//    if (_nodes) 
//      for ( int i = 0; i < _nodes->size(); i++) 
//          RET_ONERROR( _nodes->get(i)->write(f, indent) )
    return(0);
}

bool Proto::isPROTO()
{
    if (_nodes==NULL) 
       return false;
    else
       return true;
}

ProtoNode::ProtoNode(Scene *scene, Proto *proto)
  : Node(scene, proto)
{
}


Generated by  Doxygen 1.6.0   Back to index