/** * Add a line of script to the function: * Scalar x = 1; * Scalar y = 2; * Scalar z; * z = x + y; */ void ScriptLineBlock::addScript(const std::string& script) { ScriptParser parser; parser.parse( script ); const size_t n = parser.size(); for(size_t i = 0; i < n; ++i) { auto line = createLine( parser.line( i ) ); if ( line ) { m_lines.push_back(ScriptLine_ptr(line)); } else { throw std::runtime_error("Cannot create script line: " + boost::lexical_cast<std::string>(i)); } } }
void Project :: compile(ident_t filePath, Compiler& compiler, ScriptParser parser, ModuleInfo& moduleInfo, Unresolveds& unresolved) { try { // based on the target type generate the syntax tree for the file Path fullPath(StrSetting(_ELENA_::opProjectPath)); fullPath.combine(filePath); // parse SyntaxTree tree; parser.parse(fullPath.c_str(), tree/*, getTabSize()*/); // compile the syntax tree compiler.compileModule(*this, filePath, tree.readRoot(), moduleInfo, unresolved); } catch (LineTooLong& e) { raiseError(errLineTooLong, filePath, e.row, 1); } catch (InvalidChar& e) { size_t destLength = 6; _ELENA_::String<char, 6> symbol; _ELENA_::Convertor::copy(symbol, (_ELENA_::unic_c*)&e.ch, 1, destLength); raiseError(errInvalidChar, filePath, e.row, e.column, (const char*)symbol); } catch (SyntaxError& e) { raiseError(e.error, filePath, e.row, e.column, e.token); } catch (ScriptError& e) { raiseError(e.error, filePath); } }
ObjectEditorWidget::ObjectEditorWidget() { this->setLayout( new QHBoxLayout() ); QWidget * objectListContainer = new QWidget; objectListContainer->setLayout( new QVBoxLayout ); objectListContainer->layout()->addWidget( new QLabel( "Objects" ) ); objectList = new ObjectListWidget(); objectList->refreshList(); connect( objectList->selectionModel(), &QItemSelectionModel::selectionChanged, [this](){ this->changingSelection(); } ); objectListContainer->setFixedWidth( 150 ); objectListContainer->layout()->addWidget( objectList ); QPushButton * newObjButt = new QPushButton( "New" ); connect( newObjButt, &QPushButton::clicked, [this](){ bool ok; QString s = QInputDialog::getText(this, tr("New Object"), tr("Name:"), QLineEdit::Normal, tr( "NewObject" ), &ok); if (ok && !s.isEmpty()) { StructureObject obj; obj.name = s.toStdString(); display( obj ); saveCurrent(); objectList->refreshList(); hasChanged = false; objectList->seekObject( s ); } } ); objectListContainer->layout()->addWidget( newObjButt ); QPushButton * deleteObjButt = new QPushButton( "Delete" ); connect( deleteObjButt, &QPushButton::clicked, [this](){ if( objectList->currentRow() != -1 ) { QMessageBox msgBox; msgBox.setWindowTitle("Deleting Object"); msgBox.setText("Are you sure you want to delete the object \"" + objectList->item( objectList->currentRow() )->text() + "\"?"); msgBox.setStandardButtons(QMessageBox::Yes|QMessageBox::No); msgBox.setDefaultButton(QMessageBox::No); int result = msgBox.exec(); if( result == QMessageBox::Yes ) { remove( ( "Assets/objs/" + ( objectList->item( objectList->currentRow() )->text() + ".rpobj" ).toStdString() ).c_str() ); editingIndex = -1; objectList->selectionModel()->reset(); objectList->refreshList(); hide(); } } } ); objectListContainer->layout()->addWidget( deleteObjButt ); this->layout()->addWidget( objectListContainer ); //Existing objects widget noObjectSelected = new QWidget(); noObjectSelected->setLayout( new QVBoxLayout() ); noObjectSelected->layout()->setAlignment( Qt::AlignHCenter ); noObjectSelected->layout()->addWidget( new QLabel( "No object has been selected for editing" ) ); QFont nf("Tahoma"); nf.setPixelSize( 24 ); noObjectSelected->setFont( nf ); this->layout()->addWidget( noObjectSelected ); currentObjectContainer = new QSplitter( Qt::Vertical ); //currentObjectContainer->setLayout( new QVBoxLayout ); QWidget * currentObjectEditorContainer = new QWidget; currentObjectEditorContainer->setLayout( new QVBoxLayout ); nameEditor = new QLineEdit; QFont lf("Tahoma"); lf.setPixelSize( 24 ); nameEditor->setFont(lf); nameEditor->setMaximumWidth( 320 ); connect( nameEditor, &QLineEdit::textEdited, [this](){ hasChanged = true; } ); currentObjectEditorContainer->layout()->addWidget( nameEditor ); codeEditTabs = new QTabWidget(); const char * signatures[] = { "subsetRayMarch( x, y, z, out r, out g, out b ) : boolean", "distanceRayMarch( x, y, z, out r, out g, out b ) : number", "rayTrace( x, y, z, dx, dy, dy, out dist, out r, out g, out b ) : boolean" }; for( int i = 0; i < 3; i++ ) { QWidget * de = new QWidget; de->setLayout( new QVBoxLayout ); QCheckBox * check = new QCheckBox; check->setChecked( false ); check->setText( "Enabled" ); de->layout()->addWidget( check ); de->layout()->addWidget( new QLabel( signatures[i] ) ); CodeEditWidget * edit = new CodeEditWidget(); de->layout()->addWidget( edit ); edit->setEnabled( false ); connect( edit, &QTextEdit::textChanged, [this](){ hasChanged = true; } ); connect( check, &QCheckBox::stateChanged, [edit, check](){ edit->setEnabled( check->isChecked() ); } ); connect( check, &QCheckBox::clicked, [this](){ hasChanged = true; } ); codeEditTabs->addTab( de, tr("Test")); } codeEditTabs->setTabText(0, "Subset Ray Marching" ); codeEditTabs->setTabText(1, "Distance Estimated Ray Marching" ); codeEditTabs->setTabText(2, "Absolute Ray Tracing" ); //QObject::connect( //connect( check, SIGNAL( stateChanged( int ) ), [edit](int state){ edit->setEnabled( state == 0 ); } ); currentObjectEditorContainer->layout()->addWidget( codeEditTabs ); QSplitter * horizontalBottomBar = new QSplitter( Qt::Horizontal ); //horizontalBottomBar->setLayout( new QHBoxLayout ); currentObjectContainer->addWidget( currentObjectEditorContainer ); horizontalBottomBar->setFixedHeight( 256 ); QWidget * previewVerticalContainer = new QWidget; previewVerticalContainer->setLayout( new QVBoxLayout ); QLabel * prevLabel = new QLabel( "Preview" ); prevLabel->setFixedHeight( 24 ); previewVerticalContainer->layout()->addWidget( prevLabel ); NewRayMarchWidget * march = new NewRayMarchWidget( 256, 256 ); NewRayMarchCL * under = new NewRayMarchCL(); under->initialize(); march->gpu = under; previewVerticalContainer->layout()->addWidget( march ); //preview march->init(); //previewVerticalContainer->setFixedWidth( 256 ); QWidget * previewButtonBar = new QWidget; previewButtonBar->setFixedHeight( 38 ); previewButtonBar->setLayout( new QHBoxLayout ); previewButtonBar->layout()->setAlignment( Qt::AlignHCenter ); //Making the parser ScriptParser * parser = ScriptParser::makeRegular(); QPushButton * compButt = new QPushButton( "Compile Selected" ); connect( compButt, &QPushButton::clicked, [this,parser,march](){ console->log( "Parsing started" ); Block * script = parser->parse( this->codeEditTabs->currentWidget()->findChild<QTextEdit*>()->toPlainText().toStdString() ); console->log( "Parsing ended" ); console->log( "Compiling started" ); std::string outlets = ""; try { for( int i = 0; i < this->outlets->rowCount(); i++ ) { outlets += ( "frac " + this->outlets->getName( i ) + " = " + std::to_string( this->outlets->getValue( i ) ).c_str() + ";" ).toStdString(); script->variablesInScope[ this->outlets->getName( i ).toStdString() ] = VariablePacket( Value() ); } if( ( this->codeEditTabs->currentIndex() ) == 0 ) { script->variablesInScope[ "x" ] = VariablePacket( Value() ); script->variablesInScope[ "y" ] = VariablePacket( Value() ); script->variablesInScope[ "z" ] = VariablePacket( Value() ); script->variablesInScope[ "r" ] = VariablePacket( Value(), true ); script->variablesInScope[ "g" ] = VariablePacket( Value(), true ); script->variablesInScope[ "b" ] = VariablePacket( Value(), true ); std::ifstream if_a("Assets/clparts/clheader.cl", std::ios_base::binary); std::ifstream if_b("Assets/clparts/clfootergutsSUBSET.cl", std::ios_base::binary); std::ofstream of_c("Assets/temp/testAll.cl", std::ios_base::binary); std::string output = parser->textOf( script, 0, true ); of_c << if_a.rdbuf() << "bool subsetFunction( frac x, frac y, frac z, frac * r, frac * g, frac * b ){ " << outlets << output << "}" << if_b.rdbuf(); of_c.close(); march->load( "Assets/temp/testAll.cl" ); } else if( ( this->codeEditTabs->currentIndex() ) == 1 ) { script->variablesInScope[ "x" ] = VariablePacket( Value() ); script->variablesInScope[ "y" ] = VariablePacket( Value() ); script->variablesInScope[ "z" ] = VariablePacket( Value() ); script->variablesInScope[ "r" ] = VariablePacket( Value(), true ); script->variablesInScope[ "g" ] = VariablePacket( Value(), true ); script->variablesInScope[ "b" ] = VariablePacket( Value(), true ); std::ifstream if_a("Assets/clparts/clheader.cl", std::ios_base::binary); std::ifstream if_b("Assets/clparts/clfooterguts.cl", std::ios_base::binary); std::ofstream of_c("Assets/temp/testAll.cl", std::ios_base::binary); std::string output = parser->textOf( script, 0, true ); of_c << if_a.rdbuf() << "frac distanceFunction( frac x, frac y, frac z, frac * r, frac * g, frac * b, __global const float* sceneVarData ){ " << outlets << output << "}" << if_b.rdbuf(); of_c.close(); march->load( "Assets/temp/testAll.cl" ); } else if( ( this->codeEditTabs->currentIndex() ) == 2 ) { script->variablesInScope[ "x" ] = VariablePacket( Value() ); script->variablesInScope[ "y" ] = VariablePacket( Value() ); script->variablesInScope[ "z" ] = VariablePacket( Value() ); script->variablesInScope[ "dx" ] = VariablePacket( Value() ); script->variablesInScope[ "dy" ] = VariablePacket( Value() ); script->variablesInScope[ "dz" ] = VariablePacket( Value() ); script->variablesInScope[ "r" ] = VariablePacket( Value(), true ); script->variablesInScope[ "g" ] = VariablePacket( Value(), true ); script->variablesInScope[ "b" ] = VariablePacket( Value(), true ); script->variablesInScope[ "dist" ] = VariablePacket( Value(), true ); std::ifstream if_a("Assets/clparts/clheader.cl", std::ios_base::binary); std::ifstream if_b("Assets/clparts/clfootergutsTRACE.cl", std::ios_base::binary); std::ofstream of_c("Assets/temp/testAll.cl", std::ios_base::binary); std::string output = parser->textOf( script, 0, true ); of_c << if_a.rdbuf() << "bool traceFunction( frac x, frac y, frac z, frac dx, frac dy, frac dz, frac * r, frac * g, frac * b, frac * dist ){ " << outlets << output << "}" << if_b.rdbuf(); of_c.close(); march->load( "Assets/temp/testAll.cl" ); } } catch( char * error ) { console->log( ( "UNEXPECTED COMPILATION ERROR: " + std::string( error ) ).c_str(), ConsoleWidget::MESSAGE_TYPE::MSG_DIREERROR ); } console->log( "Compiling ended" ); } ); previewButtonBar->layout()->addWidget( compButt ); QPushButton * viewButt = new QPushButton( "Reset View" ); connect( viewButt, &QPushButton::clicked, [march](){ march->reset(); } ); previewButtonBar->layout()->addWidget( viewButt ); previewVerticalContainer->layout()->addWidget( previewButtonBar ); //preview horizontalBottomBar->addWidget( previewVerticalContainer ); QWidget * consoleVerticalContainer = new QWidget; consoleVerticalContainer->setLayout( new QVBoxLayout ); consoleVerticalContainer->setMinimumWidth( 256 ); consoleVerticalContainer->layout()->addWidget( new QLabel( "Console" ) ); console = new ConsoleWidget; consoleVerticalContainer->layout()->addWidget( console ); horizontalBottomBar->addWidget( consoleVerticalContainer ); currentObjectContainer->addWidget( horizontalBottomBar ); this->layout()->addWidget( currentObjectContainer );//Script edit widget currentObjectContainer->setVisible( false ); outletContainer = new QWidget; outletContainer->setLayout( new QVBoxLayout ); outletContainer->layout()->addWidget( new QLabel( "Outlets" ) ); outlets = new ValueTableWidget(); outletContainer->setFixedWidth( 150 ); outletContainer->layout()->addWidget( outlets ); QPushButton * addButt = new QPushButton( "Add" ); connect( addButt, &QPushButton::clicked, [this](){ outlets->addFullRow(); hasChanged = true; } ); outletContainer->layout()->addWidget( addButt ); QPushButton * deleteButt = new QPushButton( "Delete" ); connect( deleteButt, &QPushButton::clicked, [this](){ if( outlets->currentRow() != -1 ) { QMessageBox msgBox; msgBox.setWindowTitle("Deleting outlet"); msgBox.setText("Are you sure you want to delete the outlet \"" + outlets->getName( outlets->currentRow() ) + "\"?"); msgBox.setStandardButtons(QMessageBox::Yes|QMessageBox::No); msgBox.setDefaultButton(QMessageBox::No); int result = msgBox.exec(); if( result == QMessageBox::Yes ) { outlets->removeRow( outlets->currentRow() ); hasChanged = true; } } } ); outletContainer->layout()->addWidget( deleteButt ); this->layout()->addWidget( outletContainer ); //Outlet widget hasChanged = false; editingIndex = -1; hide(); }