Beispiel #1
0
// typetag: "ss" (inlet, outlet)
const Value Planet::link(const Value &val) {
  // std::cout << "link: " << val << std::endl;
  if (val.is_nil()) {
    return create_pending_links();
  }

  Value error;
  Object *source = object_at(Url(val[0].str()), &error);
  if (error.is_error() || !object_at(Url(val[2].str()), &error)) {
    // not found
    if (val[1].str() == "=>") {
      return add_pending_link(val);
    } else if (val[1].str() == "||") {
      // remove from pending links
      return remove_pending_link(val);
    }
    return val;
  }

  Slot   *slot = TYPE_CAST(Slot, source);
  Object *object;
  if (slot != NULL) {
    return val[1].str() == "||" ? slot->unlink(val[2]) : slot->link(val[2]);
  } else if ( (object = source->child("out")) && (object = object->first_child()) ) {
    // was a link default slots: /met/out --> /counter/in
    if ( (slot = TYPE_CAST(Slot, object)) ) {
      return val[1].str() == "||" ? slot->unlink(val[2]) : slot->link(val[2]);
    } else {
      return Value(BAD_REQUEST_ERROR, std::string("Object at '").append(slot->url()).append("' does not support links (using first child of '").append(source->url()).append("')."));
    }
  } else {
    return Value(BAD_REQUEST_ERROR, std::string("Object at '").append(source->url()).append("' does not support links (not an Outlet, Inlet or Node)."));
  }
}
Beispiel #2
0
	PROTECTED RETCODE MemReleaseBlock (void * data, Dword numBytes)
	{
		PMEMBLOCK MemBlock  = MemHead->MemBlocks;	// Current memory block
		PMEMBLOCK DataBlock = (PMEMBLOCK) data;		// Block of data to release
		PMEMBLOCK PrevBlock = NULL;					// Previous block

		DataBlock->Size = numBytes;	// Set size of block to release into memory

		if (MemHead->MemBlocks < DataBlock)	// Check whether block is beyond main memory block
		{
			while (MemBlock < DataBlock)	// Search through memory blocks via pointer arithmetic
			{
				PrevBlock = MemBlock;		// Set previous block
				MemBlock  = MemBlock->Next;	// Set current block
			}
		}

		else								// Check for other cases
		{
			MemBlock		   = MemHead->MemBlocks;// Grab main memory block
			MemHead->MemBlocks = DataBlock;			// Point main memory block to data block
		}

		MemCollectBytes (numBytes);
		// Collect memory from the memory block

		if ((PMEMBLOCK) (TYPE_CAST(Pbyte,DataBlock) + DataBlock->Size) == MemBlock)	// Check whether data block may join with upper memory block
		{																																		
			DataBlock->Size += MemBlock->Size;	// Increment data block size by size of upper block
			DataBlock->Next  = MemBlock->Next;	// Point Next field of data block beyond upper block
		}

		else
		{
			DataBlock->Next = MemBlock;	// Bind data block ahad to memory block
		}

		if (PrevBlock)	// Check whether a previous block exists
		{
			if ((PMEMBLOCK) (TYPE_CAST(Pbyte,PrevBlock) + PrevBlock->Size) == DataBlock) // Check whether lower memory block may join with data block
			{
				PrevBlock->Size += DataBlock->Size;	// Increment lower block size by size of data block
				PrevBlock->Next  = DataBlock->Next;	// Point Next field of lower block beyond data block
			}

			else
				PrevBlock->Next = DataBlock; // Bind previous block to data block
		}

		return RETCODE_SUCCESS;
		// Return success
	}
Beispiel #3
0
	PROTECTED void * MemGrabBlock (Dword numBytes)
	{
		PMEMBLOCK MemBlock  = MemHead->MemBlocks;	// Current memory block
		PMEMBLOCK PrevBlock	= NULL;					// Previous memory block
		PMEMBLOCK DataBlock = NULL;					// Data block
		Dword Size;									// Size container

		while (MemBlock)	// Check that MemBlock is not yet null
		{
			PrevBlock = MemBlock;		// Set current block as previous block

			if (MemBlock->Size >= numBytes)	// Check whether block is of at least requested capacity
				break;	// Break out of loop

			MemBlock  = MemBlock->Next;	// Grab next block in sequence
		}

		MemAllotBytes (numBytes);
		// Allot memory for the memory block

		DataBlock = MemBlock;					// Set MemBlock to DataBlock
		Size	  = MemBlock->Size - numBytes;	// Figure size difference between block size and requested bytes

		if (MemBlock == MemHead->MemBlocks)	// Check whether memory is being requested from main block
		{																			
			MemHead->MemBlocks = (PMEMBLOCK) (TYPE_CAST(Pbyte,MemBlock) + numBytes);// Point main block beyond requested block	
			MemBlock		   = MemHead->MemBlocks;								// Grab main memory block
		}

		else
		{
			MemBlock		= (PMEMBLOCK) (TYPE_CAST(Pbyte,DataBlock) + numBytes);	// Point MemBlock to new location
			PrevBlock->Next = MemBlock;												// Point previous block ahead beyond data block
		}

		if (Size != 0)	// Check whether difference is nonzero
		{
			MemBlock->Size	= Size;				// Set new memory block size
			MemBlock->Next	= DataBlock->Next;	// Point memory block ahead to next block
		}

		ZeroMemory(DataBlock,numBytes);
		// Set all bytes in data block to 0

		return (void *) DataBlock;
		// Return pointer to data block
	}
Beispiel #4
0
const Value Slot::change_link(unsigned char operation, const Value &val) {
  if (val.is_string()) {
    // update a link (create/destroy)
    
    Object * target = root_->object_at(val.str());
    if (!target) return ErrorValue(NOT_FOUND_ERROR, val.str());
    
    if (!target->kind_of(Slot)) {
      target = target->child("in");
      if (target) target = target->first_child(); // target/out/... 
      if (!target) {
        return ErrorValue(NOT_FOUND_ERROR, val.str()).append(": slot not found");
      }
    }
    
    if (kind_of(Outlet)) {
      // other should be an Inlet
      target = (Slot*)TYPE_CAST(Inlet, target);
    } else {
      // other should be an Outlet
      target = (Slot*)TYPE_CAST(Outlet,target);
    }
    
    if (!target) {
      return ErrorValue(BAD_REQUEST_ERROR, "Could not update link with ").append(val.to_json()).append(": incompatible).");
    }
    
    if (operation == 'c') {
      // create link
      if (connect((Slot*)target)) {
        //std::cout << "LINKED: " << url() << " with " << val << std::endl;
        return Value(url()).push_back("=>").push_back(target->url());
      } else {
        return ErrorValue(BAD_REQUEST_ERROR, "Could not make the connection with (").append(val.to_json()).append(").");
      }
    } else {
      // disconnect
      disconnect((Slot*)target);
      return Value(url()).push_back("||").push_back(target->url());
    }
  } else {
    return Value(info());
  }
}
Beispiel #5
0
void ObjectProxy::adopted() {
  root_proxy_ = TYPE_CAST(RootProxy, root_);
  if (root_proxy_ && type().is_nil()) {
    // try to find type
    root_proxy_->send_to_remote(ATTRS_PATH, Value(url()));
  } else if (value_.is_empty()) {
    // only get initial value if type is already there (or we won't receive the value).
    set_value(gNilValue);
  }
}
Beispiel #6
0
const Value Planet::inspect(const Value &val) {
  std::cout << "## inspect " << val << "\n";
  if (!val.is_string()) return Value(BAD_REQUEST_ERROR, "Bad arguments:'inspect' should be called with an url.");
  Value res;
  Object *object = find_or_build_object_at(val.str(), &res);
  if (!object) return res;
  Node *node = TYPE_CAST(Node, object);
  if (!node) return Value(BAD_REQUEST_ERROR, std::string("Bad target '").append(object->url()).append("':inspect only works on Nodes (class is '").append(object->class_path()).append("')."));
  return node->do_inspect();
}
// for help to create a portable version of this load function, read Ruby's dln.c file.
bool ClassFinder::load(const char * file, const char * init_name)
{
  void *image;
  void (*function)(Planet*);
  const char *error = 0;

  // load shared extension image into memory
  // --->
  if ((image = (void*)dlopen(file, RTLD_LAZY|RTLD_GLOBAL)) == 0) {
    printf("Could not open file '%s'.", file);
    if ( (error = dlerror()) )
      printf(" %s\n", error);
    else
      printf("\n");
    return false;
  }

  // get 'init' function into the image
  function = (void(*)(Planet*))dlsym(image, init_name);
  if (function == 0) {
    dlclose(image);
    printf("Symbol '%s' not found in '%s'.",init_name,file);
    if ( (error = dlerror()) )
      printf(" %s\n", error);
    else
      printf("\n");
    return false;
  }

  Planet *planet = TYPE_CAST(Planet, root_);

  // call 'init', passing planet
  if (planet) {
    (*function)(planet);
  } else {
    fprintf(stderr, "Could not cast root_ to Planet* !\n");
    return false;
  }

  return true;
}