/* * 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 #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 _eventIns; // Array _eventOuts; // Array _fields; // Array _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_ 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 _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) { }