You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
tdemultimedia/arts/builder/structure.cpp

463 lines
10 KiB

/*
Copyright (C) 1999 Stefan Westerfeld
stefan@space.twc.de
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; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "structure.h"
#include "soundserver.h"
#include "kartsserver.h"
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <fstream>
#include <kdebug.h>
#include <arts/debug.h>
using namespace std;
ExecutableStructure::ExecutableStructure()
{
}
ExecutableStructure::~ExecutableStructure()
{
// to make destructor virtual
// stop execution here?
}
void ExecutableStructure::stopExecute()
{
arts_debug("TODO: PORT: freeStructure");
}
bool ExecutableStructure::isExecuting()
{
arts_debug("TODO:PORT:isExecuting()");
return false;
}
bool ExecutableStructure::saveSession(const char *filename)
{
arts_debug("TODO:PORT:saveSession()");
#if 0
assert(execID);
ArtsCorba::StringSeq_var data;
arts_debug("saveSession");
if(Synthesizer->saveSession(execID,true,data))
{
arts_debug("ok");
FILE *file = fopen(filename,"w");
if(!file) return false;
unsigned long i;
for(i=0;i<data->length();i++) fprintf(file,"%s\n",(char *)(*data)[i]);
fclose(file);
return true;
}
arts_debug("failed");
#endif
return false;
}
Structure::Structure() :ExecutableStructure()
{
canvas = 0;
}
void Structure::setCanvas(StructureCanvas *canvas)
{
this->canvas = canvas;
}
Structure::~Structure()
{
clear();
arts_debug("~Structure (releasing structuredesc from structure)");
}
bool Structure::startExecute()
{
#if 0
assert(!execID);
arts_debug("PORT: TODO startExecute()");
// just in case synthesis has been halted before,
// restart it and hope we'll have enough computing power now
//Synthesizer->Reset();
//execID = Synthesizer->createStructure(StructureDesc,preferredservers);
assert(execID);
#endif
/* connect to the sound server */
Arts::SimpleSoundServer server = KArtsServer().server();
if(server.isNull())
return false;
/* move a copy of the structure to the server, so that there will be
no latencies in querying what to connect to what */
vector<string> *savePtr = StructureDesc.saveToList();
Arts::StructureDesc remoteSD;
remoteSD = Arts::DynamicCast(server.createObject("Arts::StructureDesc"));
assert(!remoteSD.isNull());
remoteSD.loadFromList(*savePtr);
delete savePtr;
/* create a structure builder on the server */
Arts::StructureBuilder builder;
builder = Arts::DynamicCast(server.createObject("Arts::StructureBuilder"));
/* create a local factory - this will enable the builder to create gui qt
widgets (which need to reside within an qt application to work) */
Arts::LocalFactory factory;
builder.addFactory(factory);
/* create the structure on the server */
structure = Arts::DynamicCast(builder.createObject(remoteSD));
if (structure.isNull())
return false;
structure.start();
return true;
}
void Structure::stopExecute()
{
// TODO:PORT: verify this code
structure = Arts::SynthModule::null();
}
void Structure::publish()
{
arts_debug("PORT: TODO publish()");
//Synthesizer->publishStructureDesc(StructureDesc);
}
bool Structure::valid()
{
return StructureDesc.valid();
}
string Structure::name()
{
return StructureDesc.name();
}
void Structure::rename(const char *newname)
{
StructureDesc.name(newname);
}
void Structure::addInheritedInterface(const char *iface)
{
StructureDesc.addInheritedInterface(iface);
}
vector<string> *Structure::inheritedInterfaces()
{
return StructureDesc.inheritedInterfaces();
}
void Structure::removeInheritedInterface(const char *iface)
{
StructureDesc.removeInheritedInterface(iface);
}
void Structure::saveInto(FILE *file)
{
vector<string> *list = StructureDesc.saveToList();
vector<string>::iterator i;
for(i = list->begin(); i != list->end(); i++)
fprintf(file, "%s\n", (*i).c_str());
delete list;
}
bool Structure::save(const char *filename)
{
FILE *file = fopen(filename,"w");
if (!file)
return false;
saveInto(file);
fclose(file);
return true;
}
void Structure::clear()
{
list<StructureComponent *>::iterator ci;
arts_debug("clc");
/*
for(ci = ComponentList.begin(); ci != ComponentList.end(); ++ci)
delete (*ci);
ComponentList.erase(ComponentList.begin(), ComponentList.end());
ModuleList.erase(ModuleList.begin(), ModuleList.end());
*/
for(ci = ComponentList.begin(); ci != ComponentList.end(); ++ci)
(*ci)->setSelected(true);
deleteSelected();
arts_debug("sdc");
// shouldn't do much, now that we deleted every single component of
// the structure, but we to it anyway, just to be sure.
StructureDesc.clear();
}
void Structure::retrieve(const char *pubname)
{
arts_debug("PORT: TODO: retrieve");
#if 0
arts_debug("retrieve... %s",pubname);
ArtsCorba::StructureDesc_var psd = Synthesizer->lookupStructureDesc(pubname);
arts_debug("psdlookup ok");
if(psd)
{
arts_debug("starting savetolist");
ArtsCorba::StringSeq_var strseq=psd->saveToList();
arts_debug("savetolist ok");
loadFromList(strseq);
arts_debug("loadfromlist ok");
}
arts_debug("retrieve... ok");
#endif
}
void Structure::load(const char *filename)
{
ifstream infile(filename);
string line;
vector<string> strseq;
while(getline(infile,line))
strseq.push_back(line);
loadFromList(strseq);
#if 0
FILE *infile = fopen(filename,"r");
ArtsCorba::StringSeq_var strseq = new ArtsCorba::StringSeq;
char line[1024];
unsigned long i = 0;
while(fgets(line,1024,infile))
{
// cut eventual CR and/or LFs at the end of the line
while(strlen(line) && line[strlen(line)-1] < 14)
line[strlen(line)-1] = 0;
strseq->length(i+1);
(*strseq)[i++] = CORBA::string_dup(line);
}
fclose(infile);
arts_debug(">>loadfromlist...");
loadFromList(strseq);
arts_debug("<<loadfromlist...");
#endif
}
void Structure::loadFromList(const vector<string>& strseq)
{
assert(canvas);
arts_debug(">>clear");
clear();
arts_debug("<<clear");
StructureDesc.loadFromList(strseq);
vector<Arts::ModuleDesc> *modules = StructureDesc.modules();
vector<Arts::ModuleDesc>::iterator mi;
for(mi=modules->begin(); mi != modules->end(); ++mi)
{
Module *m = new Module(*mi,StructureDesc,canvas);
m->show();
ModuleList.push_back(m);
ComponentList.push_back(m);
}
delete modules;
vector<Arts::StructurePortDesc> *ports = StructureDesc.ports();
vector<Arts::StructurePortDesc>::iterator pi;
for(pi=ports->begin(); pi != ports->end(); ++pi)
{
StructurePort *p = new StructurePort(*pi,StructureDesc,canvas);
p->show();
ComponentList.push_back(p);
}
delete ports;
}
Module *Structure::createModule(const Arts::ModuleInfo& minfo)
{
assert(canvas);
Module *m = new Module(minfo,StructureDesc,canvas);
ComponentList.push_back(m);
ModuleList.push_back(m);
return m;
}
StructurePort *Structure::createStructurePort(const Arts::PortType& type)
{ // TODO:PORT: verify this code
#if 0
arts_debug("TODO:PORT:createStructurePort");
#endif
// portname generation
unsigned long portindex = 1,l,baselen;;
char name[100];
string namebase;
if(type.direction == Arts::input) {
// this is a port where our structure puts its results
// so it is an input port, that is named out
namebase = "out"; baselen = 3;
} else {
// this is a port where our structure gets data from
// so it is an output port, that is named in
namebase = "in"; baselen = 2;
}
vector<Arts::StructurePortDesc> *sps = StructureDesc.ports();
for(l=0;l<sps->size();l++) {
string thisname = (*sps)[l].name();
if(strncmp(thisname.c_str(), namebase.c_str(), baselen) == 0 &&
strlen(thisname.c_str()) > baselen)
{
unsigned long index2 = atol(&thisname.c_str()[baselen]);
if(index2 >= portindex) portindex = index2+1;
}
}
delete sps;
sprintf(name,"%s%ld",namebase.c_str(),portindex);
arts_debug("new Portname: %s",name);
Arts::StructurePortDesc spd =
StructureDesc.createStructurePortDesc(type,name);
assert(canvas);
StructurePort *s = new StructurePort(spd,StructureDesc,canvas);
ComponentList.push_back(s);
return s;
}
list<Module *> *Structure::getModuleList()
{
return(&ModuleList);
}
list<StructureComponent *> *Structure::getComponentList()
{
return(&ComponentList);
}
long Structure::countSelected()
{
list<StructureComponent *>::iterator ci;
long targets = 0;
for(ci=ComponentList.begin();ci!=ComponentList.end();++ci)
if((*ci)->selected()) targets++;
return targets;
}
void Structure::deleteSelected()
{
arts_debug("deleteSelected...");
// remove module from the ModuleList
list<Module *>::iterator mi;
for(mi=ModuleList.begin();mi!=ModuleList.end();)
{
if((*mi)->selected())
{
mi = ModuleList.erase(mi);
}
else mi++;
}
// disconnect ports (it might be useful to get this right in the model
// instead of doing it in the view - however at it works without end
// user visible bugs like this)
list<StructureComponent *>::iterator ci;
list<ModulePort *> allPorts;
for(ci = ComponentList.begin(); ci!=ComponentList.end(); ++ci)
if((*ci)->selected())
(*ci)->dumpPorts(allPorts);
list<ModulePort *>::iterator pi;
for(pi = allPorts.begin(); pi != allPorts.end(); ++pi)
(*pi)->PortDesc.disconnectAll();
// and from the ComponentList (the future ;)
ci = ComponentList.begin();
while(ci!=ComponentList.end())
{
if((*ci)->selected())
{
delete (*ci);
ci = ComponentList.erase(ci);
}
else ci++;
}
arts_debug("deleteSelected ok.");
}
StructureComponent *Structure::componentAt(long x, long y, bool ignore_selected)
{
list<StructureComponent *>::iterator ci;
for(ci=ComponentList.begin();ci!=ComponentList.end();++ci)
{
StructureComponent *c = *ci;
if(x >= c->x() && x < c->x()+c->width() &&
y >= c->y() && y < c->y()+c->height())
{
if((c->selected() && !ignore_selected) || !c->selected()) return c;
}
}
return 0;
}